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

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

复制代码 代码如下:

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

 

复制代码 代码如下:

//造成传址假象的代码
function modifyLikeByRef(x){
  x[0] = 4;
  x[1] = 5;
  x[2] = 6;
  console.log('x = [ %s ]', x.join(', '));
}
var x = [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 {  // 表示全局作用域,下面的表示函数作用域
  var x = 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;
  */
  var x = [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]的别名了。

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

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

时间: 2025-01-30 22:05:45

JavaScript 函数参数是传值(byVal)还是传址(byRef) 分享的相关文章

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

对于"JavaScript 函数参数是传值(byVal)还是传址(byRef)"这个问题,普遍存在一个误区:number,string等"简单类型"是传值,Number, String, Object, Array等"复杂类型"是传址.这样不对吗?为什么会有这样的误区?看一下这两段代码: 复制代码 代码如下: //造成传值假象的代码function modifyLikeByVal(x){  x = 1;  console.log('x = %d'

深入理解JavaScript函数参数(推荐)_javascript技巧

前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数. arguments javascript中的函数定义并未指定函数形参的类型,函数调用也未对传入的实参值做任何类型检查.实际上,javascript函数调用甚至不检查传入形参的个数 function add(x){ return x+1; } console.log(add(1));//2 console.log(add('1'));/

JavaScript函数参数使用带参数名的方式赋值传入的方法

 这篇文章主要介绍了JavaScript函数参数使用带参数名的方式赋值传入的方法,实例分析了javascript函数传递参数的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了JavaScript函数参数使用带参数名的方式赋值传入的方法.分享给大家供大家参考.具体分析如下: 这里其实就是在给函数传递参数的时候,可以使用 参数名:参数值的方式传递,这样不会传递错.不过下面的代码是通过字典来实现的,不像python原封就支持这样的方法 ? 1 2 3 4 function

JavaScript函数参数使用带参数名的方式赋值传入的方法_javascript技巧

本文实例讲述了JavaScript函数参数使用带参数名的方式赋值传入的方法.分享给大家供大家参考.具体分析如下: 这里其实就是在给函数传递参数的时候,可以使用 参数名:参数值的方式传递,这样不会传递错.不过下面的代码是通过字典来实现的,不像python原封就支持这样的方法 function foo({ name:name, project:project}) { Print( project ); Print( name ); } 调用方法 foo({ name:'soubok', projec

深入理解javascript函数参数与闭包_javascript技巧

最近在学习javascript的函数,函数是javascript的一等对象,想要学好javascript,就必须深刻理解函数.本人把学习的过程整理成文章,一是为了加深自己函数的理解,二是给读者提供学习的途径,避免走弯路.内容有些多,但都是笔者对于函数的总结. 1.函数参数 1.1:参数是什么 1.2:参数的省略 1.3:参数默认值 1.4:参数传递方式 1.5:同名参数 1.6:arguments对象 2.闭包 2.1:闭包定义 2.2:立即调用的函数表达式(IIFE, Immediately

浅谈JavaScript函数参数的可修改性问题_javascript技巧

一道笔试题思考而来的,通常情况下没人会在函数内部修改参数值.这里仅拿出来讨论,有三种方式可以修改. 1,直接修改函数声明时的形参 复制代码 代码如下: function f1(a) {     alert(a);     a = 1;//修改形参a     alert(1 === a);     alert(1 === arguments[0]); } f1(10); 函数f1定义了参数a,调用时传参数10,先弹出10,修改a为1,弹出两次true,a和arguments[0]都为1了. 2,通

Javascript函数参数 返回值 调用例子

一,函数定义调用 Function(函数)类型实际上是对象.每个函数都是Function类型的实例,而且都与其他引用类型一样具备属性和方法,由于函数是对象,因此函数名实际上也是一个指向函数对象的指针. (1)典型的函数声明 function slide(arguments){ //...code } (2)以函数表达式的形式定义函数 var slide = function(arguments){ //...code } 虽然上面两种方式逻辑上是等价的,但是还是有点小区别: 区别一:例一中的函数

javascript 函数参数限制说明_javascript技巧

测试结果: safari 下是65535个.即 ushort 来存储(2字节 16个1).更多的则忽略. 其他浏览器 至少是int.MaxValue .据说FireFox 甚至是用long 来维护 实参数. 其他浏览器 也许是int 或者可能是uint .这个就不管了. 毕竟我们知道了瓶颈 在 65535. 基于 以上基础.可以在 连接数组时 考虑优先采用 [].push.apply(a,b) 代替 a=a.concat(b);  我们只需要注意 对于safari 来说 b的length不能超过

详解javascript函数的参数_javascript技巧

javascript函数可以用任意多个参数来调用,而不用管函数定义时指定了几个参数.因为函数是弱类型的,没有方法去声明它所期望的参数类型,并且给任何函数传递任何类型的值都是合法的. 1.Js函数可以传入不同的参数,如 function writeNString(strMsg){ document.write(strMsg + "<br>"); } 2.Js函数返回值,js函数可以将运行的结果返回,函数可以视为一个黑盒子,使用参数输入数据后产生所需的运行结果,如 functi