JavaScript中参数传递方式详解
作者:十里八乡有名的后俊生
在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,重新复制的标识符会指向新的内存空间。
到此这篇关于JavaScript中参数传递方式详解的文章就介绍到这了,更多相关javascript参数传递内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!