1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > JS中的函数参数传递到底是按值传递还是按引用传递

JS中的函数参数传递到底是按值传递还是按引用传递

时间:2019-06-23 10:11:20

相关推荐

JS中的函数参数传递到底是按值传递还是按引用传递

首先我们知道JS中的数据类型大致可以分为简单数据类型和复杂数据类型;

当我们声明一个变量并给它赋值时,可以赋给其简单值和复杂值(以下堆内存和栈内存的地址表示均随意取的,只是为了区分,不代表真实的内存地址);

针对简单数据类型:

例1

var simpleData1 = 18var simpleData2 = simpleData1simpleData2 = 19console.log(simpleData1 ) //打印出18

以上例子的过程为:先给simpleData1 在栈内存中分配一个地址s101,里面保存数字18,然后将simpleData1赋给simpleData2 ,相当于紧接着在栈内存中又分配一个地址s102,里面同样保存数字18,这时再将s102中的内容变成19,这当然不会影响s101中的内容。

针对复杂数据类型,以数组为例

例2

var arr1 = ['zyp','zyp','zyp']var arr2 = arr1arr2[0] = 'zyp1'console.log(arr1) //打印出 ["zyp1", "zyp", "zyp"]

以上例子的过程为:先在堆中开辟一块地址h1001来存数组[‘zyp’,‘zyp’,‘zyp’],同时将该堆内存的地址h1001存放在栈内存s103中,然后再在栈内存中开辟一个地址s104同样存放h1001,这时arr1和arr2指向同一块堆内存,改变其中的值会同时反映在变量arr1和arr2上。

例3

var arr1 = ['zyp','zyp','zyp']var arr2 = arr1arr2 = ['zyp1','zyp1','zyp1']arr2[0] = 'zyp2'console.log(arr2) //打印出 ["zyp2", "zyp1", "zyp1"]console.log(arr1) //打印出 ["zyp", "zyp", "zyp"]

以上例子的过程为:跟上面一样,先在堆中开辟一块地址h1001来存数组[‘zyp’,‘zyp’,‘zyp’],同时将该堆内存的地址h1001存放在栈内存s103中,然后再在栈内存中开辟一个地址s104同样存放h1001,这时arr1和arr2指向同一块堆内存。不同的是:这时我们又在堆内存中开辟出一块新的地址h1002来存放新数组[‘zyp1’,‘zyp1’,‘zyp1’],新地址h1002存放在s104中,这时arr2中保存的地址已经由h1001变成了h1002, 这时再改变h1002对应的堆内存中的值,便和arr1没有任何关系了。

明白了上述赋值过程再来理解函数传参便是一个道理了

function changeObj(arr1) {arr1= ['a1', 'a1', 'a1']}var arr = ['a', 'a', 'a']changeObj(arr)console.log(arr) // 打印出["a", "a", "a"]

这个例子中:假设数组[‘a’, ‘a’, ‘a’]在堆内存中对应的地址为:h2001, 实参arr在栈内存中对应的地址为s201, 里面保存的是h2001。调用changeObj函数时,将arr复制给arr1,这里对应的操作是自动将在栈内存中分配一块地址s202来保存h2001,因此arr和arr1对应的是同一块堆内存,但这时又在堆内存中开辟新空间h2002来保存数组[‘a1’, ‘a1’, ‘a1’],h2002保存在arr1对应的栈内存s202中,这里的道理就和例3是一样的了

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。