zl程序教程

您现在的位置是:首页 >  前端

当前栏目

JavaScript函数参数是传值(byVal)还是传址(byRef)分享

JavaScript 分享 还是 传值 函数参数 ByVal ByRef
2023-06-13 09:15:02 时间

对于“JavaScript函数参数是传值(byVal)还是传址(byRef)”这个问题,普遍存在一个误区:number,string等“简单类型”是传值,Number,String,Object,Array等“复杂类型”是传址。
这样不对吗?为什么会有这样的误区?看一下这两段代码:

复制代码代码如下:

//造成传值假象的代码
functionmodifyLikeByVal(x){
 x=1;
 console.log("x=%d",x);
}
varx=0;
console.log("x=%d",x);//输出x=0
modifyLikeByVal(x); //输出x=1
console.log("x=%d",x);//输出x=0  x没变!

复制代码代码如下:

//造成传址假象的代码
functionmodifyLikeByRef(x){
 x[0]=4;
 x[1]=5;
 x[2]=6;
 console.log("x=[%s]",x.join(","));
}
varx=[1,2,3];
console.log("x=[%s]",x.join(","));//输出x=[1,2,3]
modifyLikeByRef(x); //输出x=[4,5,6]
console.log("x=[%s]",x.join(","));//输出x=[4,5,6]  x变了!

于是,由以上代码得出结论,“简单类型”作为参数是传值(byVal)的,“复杂类型”作为参数是传址(byRef)的。

问题出在哪呢?

仔细观察两个函数,就可以发现一点:
在byVal中,是直接修改了参数x:x=1;
而byRef中,是修改参数x的成员:x[0]=4;x[1]=5;x[2]=6;

本人由此得出猜想:在JavaScript中,所有的变量或成员,都是一个指针,在修改变量或成员值的时候,其实是修改了该指针的地址。

这样上面的代码就可以得到解释了:

在“byVal”中:

复制代码代码如下:
global{ //表示全局作用域,下面的表示函数作用域
 varx=0; //初始化指针x并指向数字0
   fun(x){
     x=global.x;//传入参数global.x;fun域的x指针地址与global域的x指针地址一样指向数字0
     x=1;//修改fun域的x指针地址,指向数字1;
   }//fun域结束,global域中的x指针没改变
}

在“byRef”中:
复制代码代码如下:
global{ //表示全局作用域,下面的表示函数作用域
 /*
   初始化指针x并指向数组[1,2,3]
   其实是x的三个成员0,1,2,分别指向1,2,3;
 */
 varx=[1,2,3]; 
   fun(x){
     x=global.x;//传入参数global.x;fun域的x指针地址与global域的x指针地址一样指向数组[1,2,3]
     /*
      在fun域中的x没有再被改变
      紧接着修改fun域中的x(也就是global.x)三个成员指针的指向
     */
     x[0]=4;
     x[1]=5;
     x[2]=6;
   }//fun域结束,global域中的x指针没改变,但其三个成员指针被改变了,于是就看到我们输出的结果
}

那这段代码怎么解释呢???
复制代码代码如下:
(function(a,b){
   arguments[0]=1;
   b=2;
   console.log(arguments,a,b);
})(-1,-2);

只能说a,b...,是arguments[0],...[n]的别名了。

如果有不对的地方,请指出来,谢谢。

如果有更好的解释,欢迎大家分享。