其次,我们要明白实际发生的操作:
var o1={b:1}
实现了在堆内存中创建了一个对象{b:1},o1则存储了该对象在堆内存中的地址,即o1是一个指针,指向{b:1};
同理,var o2={b:1}
也在堆内存中创建了一个对象{b:1},o2存储了该对象在堆内存中的地址,即o2也是一个指针,指向{b:1};
并且,由于两个相同的对象{b:1}是先后创建,在堆内存中也不是存储在相同的地址。
然后,我们还需要知道:
在JavaScript中,引用类型(对象、数组、正则、Date、函数)的比较,实际上是比较指针是否指向存储器中的同一段地址,只有指向同样的地址才能相等。
显然,o1这个指针指向堆内存中创建的第一个对象{b:1};
o2指针则指向堆内存中创建的第二个对象{b:1};
但两个对象相对,并不是同一个对象,故o1和o2并没有指向同样的堆内存地址,故而并不相等。
我们再看常见的应用:
var o={a:1}; o.__proto__===Object.prototype;//true
对象o的构造函数是Object,Object有一个prototype
属性,并且prototype是一个指针,他指向存储器中的一个对象,此对象将会被由构造函数创建的对象实例所共享。
作为Object的实例,o也有一个指针__proto__
,它也指向Object的prototype
属性指向的对象。
这里的全等返回true,则清楚地表明了两者指向同样的堆内存地址,即指向的是同一个对象。
我们如果想主动让两个引用类型指向同样的对象,如何操作呢?
var obj1={b:1}; var obj2=obj1; obj1===obj2;//true obj1==obj2;//true
可以看到,对于引用类型,直接使用'='赋值实际上就是使两者指向同一个对象。
故而,我们猜测,如果通过obj1修改了对象的值,obj2再次访问时将看到修改后的对象:
obj1.name='ls'; obj1;//{b: 1, name: "ls"} obj2;//{b: 1, name: "ls"}
的确如此。作为对比:
o1.name='ls'; o1;//{b: 1, name: "ls"} o2;//{b: 1}
那么,对于基本类型呢?
var s1=1; var s2=2; s1===s2;//true
在JS中,对于基本类型,只需其值相等,则两个变量就相等。
3、引用
首先,我们要深入理解引用类型的值。
前面我们看到,obj1和obj2指向堆内存中存储的同一个对象。当我们访问obj1和obj2时,都会返回同一个对象。可以说:obj1的值和obj2的值相同。
对于o1和o2,他们指向堆内存中不同地址的两个{b:1}对象,o1和o2拥有不同的值。
因此,对于引用类型,我们所说的值,指的是保存在内存中的对象。如果是同一对象,则值相同,不同对象则值不同。
在JS中,传递参数都是按值传递的。比如:
var a1=1,b1=2; function add(a,b){ a++; b--; return a+b; }; add(a1,b1);//3 a1;//1 b1;//2
这里,函数add中的形参a、b分别得到变量a1、b1的值的拷贝,这便是按值传递。
在add函数执行环境中对a、b操作不会影响到全局变量a1、b1。
再看引用类型:
function setName(obj){ obj.name="Nicholas"; obj=new Object(); obj.name="Greg"; } var person=new Object(); setName(person); alert(person.name);//"Nicholas"
执行setName(person)
时,person指向的内存中的地址便被传入obj,使得obj也指向同样的内存地址,即同一个对象。这里的按值传递,传递的是内存地址。
如果通过obj修改该对象,外部访问person便也能体现出来。
我们可能有一个疑问,既然是指向同一个对象,为什么不是按引用传递呢?
首先,我们看到函数内部对obj重新进行了赋值,使得obj指向新创建的对象。如果是按引用传递,那么外部person便也会指向新创建的对象。实际上,person还是指向原先的对象。
对于引用类型的按值传递,其实可以更加通俗地理解:
1、实参将指向的内存地址传递给形参 ,按值传递的值指的是内存地址;
2、形参修改了它和实参共同指向的对象后,外部的实参会反映出来;
3、但形参始终无法修改实参指向的内存地址,即如果将形参指向新的对象,实参并不会指向新的对象。
基于以上3点,我们就不难理解上面代码运行的结果了。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数组操作技巧总结》、《JavaScript事件相关操作与技巧大全》、《JavaScript数据结构与算法技巧总结》、《JavaScript操作DOM技巧总结》及《JavaScript字符与字符串操作技巧总结》
希望本文所述对大家JavaScript程序设计有所帮助。
Copyright © 2019- sarr.cn 版权所有 赣ICP备2024042794号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务