JS参数之按值传递、引用传递和共享传递
圣人不死,大盗不止。 --庄子·外篇·胠箧第十
在JavaScript中,参数的数据传递方式一般是按值传递、引用传递,今天遇到有人问如下这个问题
const obj = {
value: 1
};
function foo(o) {
o = 2;
console.log(o); //2
}
foo(obj);
console.log(obj.value); // 1
console.log(obj); // { value: 1 }
问为什么obj的值没有改变,按照引用传递的方式,最后一行打印的值不是2,而是{ value: 1 }
,
一开始给我也问懵了。确实,最近写iOS代码比较多,按照OC语言的逻辑,如果原先存在一个引用型数据类型A,给这个A赋值引用数据类型B,那么就会A等于B,A和B的内存地址是同一块,原先的A就不存在了。如果按照这个逻辑,确实应该打印2,但是!这是JS,不是OC,反应了片刻,和他简单介绍了JS参数传递的几种方式:
按值传递
这个是最基本的传递方式,最符合直观认知的。大家看一下代码就会明白,即使不会JS会、没啥编程经验的人也能理解。
function add(param){
param+=10;
console.log(param);//11
}
const num = 1;
add(num);
console.log(num);//1
这里,参数param的改变对于num是没有任何影响的,因为这里是num的值复制给了函数add内部的局部变量param,所以在函数内部改变param的值并不会影响外部num的值。
引用类型
红宝书中这么介绍引用类型的:
ECMAScript 中所有函数的参数都是按值传递的。这意味着函数外的值会被复制到函数内部的参数 中,就像从一个变量复制到另一个变量一样。如果是原始值,那么就跟原始值变量的复制一样,如果是 引用值,那么就跟引用值变量的复制一样。
话不多说,上代码:
const value = {
value: 1
};
function fun(o) {
o.value = 2;
console.log(o.value);//2
console.log(o);//{value: 2}
}
fun(value);
console.log(value);//{value: 2}
console.log(value.value);//2
函数内部对形参的操作影响到了外部实参,这里就是引用类型。hba
共享类型
那什么是共享类型呢?
说实话我暂时没在红宝书中找到这种说话,但是'坊间'一直流传着共享类型的传说。
还是刚刚那段代码:
const obj = {
value: 1
};
function foo(o) {
o = 2;
console.log(o); //2
}
foo(obj);
console.log(obj.value); // 1
console.log(obj); // { value: 1 }
简单来说就是:对于传递到函数参数的对象类型,如果直接改变了拷贝的引用的指向地址,那是不会影响到原来的那个对象;如果是通过拷贝的引用,去进行内部的值的操作,那么就会改变到原来的对象的。
意味着,这段代码的执行关键就在 o = 2;
将原先存放参数o的内存地址,存放了2(这里可能对于地址更换的细节有出入,但是不影响理解),也就是原先的参数o和obj没有任何关系了,转而存放了2这个值,赋值操作导致标识符发生了重新绑定Rebinding,重新复制的标识符会指向新的内存空间。
例子
最先看一个简单的例子
const data = {
user:[
{name:'张三',age:18},
{name:'李四',age:20},
]
}
const user = data.user[0];
data.user[0]=null
console.log(user)
const data2 = {
user:[
{name:'张三',age:18},
{name:'李四',age:20},
]
}
const user2 = data2.user[0];
user2.name = '王五'
console.log(user2)
这里会打印什么?答案是:
{ name: '张三', age: 18 }
{ name: '王五', age: 18 }
这里可能会有人有疑问,既然是引用类型,为什么改变data.user[0]
里面的数据,不会影响到user
?
这是因为共享传递传递/引用传递存储的是地址,这里并没有改变地址指向的东西,而是将data.user[0]里面存储的地址替换成了null,并没有沿着地址改变地址指向的数据
引用
call by sharing——JavaScript中“共享传参”和“按值传参”的理解
JavaScript 是如何工作的:JavaScript 的共享传递和按值传递-腾讯云开发者社区-腾讯云
JavaScript高级程序设计(第4版)
转载自:https://juejin.cn/post/7277395904219086848