先看下面2个奇怪的现象 :
⚽第一个奇怪的现象:当我们把一个对象赋值给另外一个对象,另外一个对象键值的更改,也会影响原来的对象键值对
结果都是{name:‘heihei’,age:19,location:‘sz’}
解释说明:我们最终obj和obj2的结果都是上面那个,发现没有,我们把obj赋值给obj2,obj2把name的值给改为了“heihei”,然后结果打印出来的obj的name值也变了,我们在这里发现,当我们把一个对象赋值给另外一个对象,另外一个对象键值的更改,也会影响原来的对象键值对。
⚽第二个奇怪的现象:两个一模一样的对象不相等
结果是:false
⚽原理解释:
我们的数据存储空间分为两种:栈和堆,简单数据类型存储在栈中,复杂数据类型存储在堆中,这也是基本数据类型和复杂数据类型的最大的区别:存储上的区别;图示如下:
因为基本数据类型都存储在栈里面,所以我们定义的对象名其实也是在栈里存储着,见栈里面的obj1和obj2,键值对在堆里面存储着,然后放这些键值对的地方都有一个地址,我们平时定义的对象数据类型,其实就是将存储在堆里的放键值对这些数据的地址拿给存储在栈里的对象名obj1,当我们把obj1赋值给mvobj1时,其实是将地址赋值给了这个mvobj1,当mvobj1改变name等键的value值时,其实就是把堆里面的键值对改了,而obj1也是指向的这些键值对,所以这就是obj1的属性值也变了的原因,因为他们指的都是同一个地方的键值对,而当我们再创建一些和0xf252键值对一样内容的键值对,也就是堆里面的0x453,让0bj2指向这个地址,这样虽然obj1和obj2指向的键值对的内容是一样的,但是它们的地址不一样,因为obj1和obj2其实等于的是这个地址,它们的地址不一样,怎么会相等呢。
⚽当我们理解了上面的存储原理以后,我们再来将上面那个“第一个奇怪现象”改一改,看怎么实现将一个对象赋值给另一个对象,另一个对象更改属性,第一个对象的属性不会受影响,代码如下:
<script>
var obj = {
name :'lili',
age : 19,
location : "sz"
}
var obj2={}
for(var i in obj){
//遍历出来的obj[i]指的是值value
//而新定义的对象obj2[i]代表的是键key
obj2[i] = obj[i]
}
obj2.name='wuwuwu'
console.log(obj,obj2)
</script>
结果:obj的结果是:{name:"lili",age:19,location:"sz"}
obj2的结果是:{name:"wuwuwu",age:19,location:"sz"}