- 简单值(基本标量)
总是通过值拷贝来赋予,null,undefined,string,number,boolean.
1 <script type="text/javascript"> 2 var num = 3; 3 var str = "a"; 4 var bol = true; 5 var nul = null; 6 var und = undefined; 7 function change(a){ 8 if(typeof a == 'number'){ 9 a = 4; 10 } 11 if(typeof a == 'string'){ 12 a = 'b'; 13 } 14 if(typeof a == 'boolean'){ 15 a = false; 16 } 17 //注意null的类型是object 18 if(typeof a == 'object'){ 19 a = 'notNull'; 20 } 21 //undefined即是类型,也是该类型得值。 22 if(typeof a == 'undefined'){ 23 a = 'lala'; 24 } 25 console.log('改变后的值'+a); 26 } 27 change(num); 28 change(str); 29 change(bol); 30 change(nul); 31 change(und); 32 console.log('原值'+num); 33 console.log('原值'+str); 34 console.log('原值'+bol); 35 console.log('原值'+nul); 36 console.log('原值'+und); 37 </script>
将简单值当参数传入函数后,因为传入的是原值得拷贝,所以无论在函数里如何变化这个参数,原值依然是原值,不会受影响。
- 复合值,object(包括array,function,和所有的对象包装器)
<script> var arr1 = [1,2,3]; var arr2 = arr1; arr2.push(4); console.log(arr1);//[1,2,3,4] console.log(arr2);//[1,2,3,4] arr2=[5,6,7,8]; console.log(arr1);//[1,2,3,4] console.log(arr2);//[5,6,7,8] </script>
arr1是[1,2,3]的引用,arr1赋值给arr2后,arr2也指向了[1,2,3]。此时arr1和arr2同时指向了同一个数组值,所以arr2中push了一个4进来,在arr1中能得到同步反馈。就好像arr1和arr2住在同一个房间里,谁对房间([1,2,3])做了一点改变,这个改变将同时影响两个人。当arr2=[5,6,7,8]后,再显示arr1和arr2,值不一样了。这也很好理解,arr2现在成了[5,6,7,8]的引用了,相当于自己找了另外一间房间,做出的改变当然不能再影响到另外一个人了。
再来看下面这段代码
<script> var arr = [1,2,3]; function change(obj){ obj.push(4); obj=[13,14]; obj.push(520); } change(arr); console.log(arr);//先猜猜看输出什么 </script>
公布正确答案,[1,2,3,4]。为什么不是1314520???
还记得前面举得换房间的例子吗。把arr当参数传入的时候,obj也成了[1,2,3]引用,所以第一次push的4的时候,两者是同在一个房间的,当obj=[13,14]的时候,说明obj找到了一生一世的所爱,到宾馆开房去了,不在同一个房间了,那后来push进来的520,秀恩爱,跟arr已经没有关系了。
一图以蔽之,刚开始两者指向同一个数值值,后来其中一个指向了另一个数组。言情一点说,就是刚开始的时候两个人心向一处([1,2,3]),后来一者见异思迁,心中有了别人([4,5,6]),分手了,相互没关系了,那输出的值肯定不一样呀。
故事到这里本该结束了,可是简单值(就是string,number那群屌丝)表示不服气,为什么同样是当参数传入,复合值可以通过函数改变自身,我们却不可以,难道屌丝就没有逆袭的机会吗?
机会还是要给的,来,请看代码。
<script> var number = 3; var obj = {a:number}; function nixi(o){ o.a = 666; } nixi(obj); number=obj.a; console.log(number);//666,逆袭成功 </script>
哈哈,简单值想通过函数改变,就得曲线救国,先变成对象的得一部分,然后传入函数,之后再把改变后的值赋值回来。这是我目前能想到的方法。