今天在逛sf的时候发现一个关于vue修改data时的一个传参问题,原问题是一个方法传入了一个data内数组变量作为参数,并在该方法内对这个参数进行重新赋值,类似于下列情况
然后一个方法:
问题差不多就是这样的,这样的结果是这个someData并没有受到改变,这里牵涉到的问题是关于JavaScript的参数传递
1 var a='000'; 2 var b=[1]; 3 function setData(aa,bb){ 4 aa='123'; 5 bb=[1,2,3]; 6 } 7 setData(a,b);
8 console.log(a) //'000'
9 consloe.log(b) //[1]
和开始的那个问题是一样的,修改后并不影响a和b的输出,因为在《JavaScript高级程序设计》书中 很显示的提醒了,无论是基本类型的值还是引用类型的值都是按值传递的,这里的按值传递是什么意思呢?
对于基本类型:
因为是保存在栈内存中的,所以按值传递的意思是直接复制了一个该基本类型值得一个副本
1 var a=123; 2 function setData(num){ 3 return ++num; 4 }; 5 var b=setData(a); 6 console.log(a);//123 7 console.log(b)//124
这样就清楚了传进去的a并不是a本身,而是复制的a的一个副本,任何操作都不会影响原来的a;
对于引用类型:
保存在堆内存中,而且在栈内存中有一个指向该堆内存的指针,在读取这个引用类型的值时先直接读取到栈内存中指针地址,然后得到指向的堆内存。
所以在应用类型的复制时,时也是按值复制的,只不过这个值是栈内存中的一个指向堆内存中的一个地址。千万记住并不是按引用传递的
1 var a=[1,2]; 2 var b=a; 3 a.push(3) 4 console.log(b)//[1,2,3] 5 6 7 var a=[1,2]; 8 var b=a; 9 a=[1,2,3] 10 console.log(b)//[1,2]
注意区别上面两段代码的区别 一个是push的操作,一个是赋值的操作,同样是b对引用类型的a进行赋值。后者这种就是经常会遇到的坑,坑,坑!前面不是说指向同一个内存地址,应该值是相同的。
前面这段代码是可以的,因为是对数组a进行的push操作,实际上是向原数组增加了一个元素,a的指针地址还是指向的原来的堆内存;
但是后面这段代码,这里a=[1,2,3] 实际上是将a中的指针地址改变成了指向了一个新的保存着数组【1,2,3】的堆内存地址,所以a和b已经没有任何关联了。
在一些常见的基础面试中也会经常遇到类似上面提到的一些坑坑,梳理并实际简单的实践一下会有新的认识!