js函数参数传递
《JS高程3》4.1.3中:ECMAScript中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制为函数内部的参数,就和把值从一个变量复制到另一个变量一样。
正如书中所说,“有不少开发人员在这一点上可能感到困惑”,很不幸,我就是那一部分人。
本文一是看高程整理的笔记,另一方面是自己有很多不理解的地方,望理解的可以解开我的困惑。
以下内容红色部分为是我自己内心yy,就是我理解有偏差的地方,如果懒得看文章,这直接看红色文字。
复制变量值
先复习下js中复制变量值
ECMAScript变量包含两种不同的数据类型,
- 基本类型值
- 引用类型值
复制基本类型
会开辟一个新的内存空间,将值复制到这个新的内存空间
var num1 = 5;
var num2 = num1;
![](https://i-blog.csdnimg.cn/blog_migrate/434c29205aa04af2e75b4dc7b6601470.png)
复制引用类型
当从一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量中的对象中的值复制一份到为新变量分配的空间中。不同的是,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象。
var obj1 = {};
var obj2 = obj1;
obj2.name = '张三';
![](https://i-blog.csdnimg.cn/blog_migrate/09a29c3d0bbcba0da2baa5767857ae10.png)
如上,obj1保存的是对象的指针地址,obj2复制了这个指针地址,obj1,obj2的指针同时指向同一个堆内存中对象,为obj2添加name属性,更改的是堆内存中的对象。
重点来了,以下高程这个章节没有讲
var obj1 = {};
var obj2 = obj1;
obj2.name = '张三';
obj2 = {name:'李四'};
![](https://i-blog.csdnimg.cn/blog_migrate/596d016e305a2e04bdb4fbdd5e98a449.png)
函数参数传递
ECMAScript中所有函数的参数都是按值传递的。这句话令我非常困惑。最后在说哪里困惑。请继续看。
基本类型传递
在向函数参数传递基本数据类型的值时,被传递的值会被复制给一个局部变量。
var num1 = 1;
var result = addTen(num1);
function addTen(num){
return num += 10;
}
console.log(num1,result)//1,11
这里,函数addTen有一个形参num,实际上是函数的局部变量,调用函数时,变量num1作为参数传递给函数的形参num,这个过程是就是上面的复制基本类型,所以num1与函数局部变量num互不影响
引用类型传递
JS高程p70,在向参数传递引用类型的值时,会把这个值在内存中的地址复制给函数局部变量。wtf,这不就是按引用传递么-_-
var person = {};
setName(person);
function setName(obj){
obj.name = '张三';
console.log(obj)//{name:'张三'}
}
console.log(person)//{name:'张三'}
对于这段代码,高程的原文是
在这个函数内部,obj和person引用的是同一个对象,换句话说,即使这个变量按值传递的,obj也会按引用来访问同一个对象
上面代码的执行结果很容易接受,但是原文这个说法很难接受。
1.既然引用的同一个对象,那么传递的就是地址,这不就是按引用传递么。
2.如果要说传递地址这个过程 可以理解为按值传递(将存储的地址传递),那么引用类型的复制,都可以说是按值传递(将存储的地址传递)了,就不存在基本类型与引用类型这个概念了。 感觉双标了。。
原文为了论证继续函数是按值传递的,补加了下面这个例子。
var person = {};
setName(person);
function setName(obj){
obj.name = '张三';
obj = {};
obj.name = '李四';
console.log(obj)//{name:'李四'}
}
console.log(person)//{name:'张三'}
原文:如果person是按引用传递的,那么person就会自动修改为指向其name属性值为’李四’的新对象。
我认为这个论证没有到点上,上面复制引用类型那段蓝色文字跟这个不是一样的么
小结
所以我现在急需解决的问题就是
- 按值传递,按引用传递的真正概念到底是什么,网上还有一种说法说这个是按分享传递。
- 是不是我理解尼古拉斯.泽卡斯所说的这部分内容有问题。
未完,如果问题解决会补充。