JavaScript基础深入之
Posted 石涛涛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript基础深入之相关的知识,希望对你有一定的参考价值。
JS的数值类型是分为两类:基本数据类型和引用数据类型。
基本类型占据的内存栈空间,引用类型被保存在堆空间。引用类型赋值的变量也是被保存在栈空间的,它的作用类似于电视遥控器,负责操作堆空间内指向的对象。
var num = 10; var change = function(obj){ obj = obj+10; return obj; } var result = change(num); console.log(result)//20 console.log(num)//10
上面例子把num作为参数传入函数change里面,但是对参数obj的操作并不会影响num原本的值,因为参数是按照值传递的,对于基本数据类型,这里没有什么疑议。
var a = {value:"teacher"}; var b = a; b.value = "student"; console.log(a);//{value:"student"} b = 2; console.log(a);//{value:"student"}
看上面的代码,a变量指向的是一个对象,将a赋值给b变量,这时a和b同时指向了一块内存地址,所以a和b都可以对对象{value:"teacher"}进行操作。当b的value值修改为"student"时,a变量的value值也发生的改变,因为他们操纵的是一块内存地址。但是当我们给b赋值数值2时候,a变量不会改变。带着这个问题,我们看一下JS函数参数的传递。
var object = new Object(); var change = function(obj){ obj.name = "jim"; } change(object); console.log(object);//{name: "jim"}
可以看到和我们预想的效果是一致的,还是那句话,变量object和参数obj指向的是一块内存,改变obj就是改变了object。但是这个例子会给我们一种错觉,就是参数是按照引用传递的。js红皮书里面对此有做解释,不管是基本类型还是引用类型,参数都是值传递。参照上一个例子我们在写一个函数的改变参数引用指向的示范。
var object = new Object(); var change = function(obj){ obj.name = "jim"; obj = new Object(); obj.name = "carry"; } change(object); console.log(object);//{name: "jim"}
变量object并没有随着参数obj后续的改变而变化。我们不妨随着红皮书作者的思路深入推算一下,个人认为可以分两个层面理解这种传递信息:
层面1:只要是对对象内部的操作,我们可以认为这是引用,这块内存地址相当于object变量和参数obj的连接桥梁,不管是谁操作它,另一个都会有变化。
层面2:任何一个变量的引用地址发生变化的时候,即参数obj指向了其他的内存地址,这时候可以理解为值传递。相信红皮书作者的意思就是这样。变量object和参数obj之间的连接桥梁断掉了,自然参数obj不会对object变量产生影响。而且,局部变量obj指向的新内存地址也会随着函数调用完成之后被GC回收掉。
相对于红皮书作者的参数按值传递的解释,网友们给出了一个看法,就是介于值传递和引用传递之间还有一个共享传递。
其实共享传递只是一种叫法,你可以认为是引用,也可以认为是值,还可以认为是共享。
但是相对于叫法,我们更应该关注的是它内部的原理,即什么情况下两个变量会相互影响,什么情况下不会影响。
以上是关于JavaScript基础深入之的主要内容,如果未能解决你的问题,请参考以下文章