赋值和浅拷贝的区别

一直以为对象赋值和对象浅拷贝是一样的,但实际上它们还是有很大差异。

先看赋值,将一个对象赋值给一个新的对象的时候,赋的其实是该对象在栈中的地址,而不是堆中的数据。 也就是一个对象的改变就会改变另外一个对象。

再看浅拷贝,浅拷贝会创建一个对象,再去遍历原始对象,如果原对象的属性值是基础类型,那么就拷贝基础类型,如果是引用类型,则拷贝的是指针。

是不是有点蒙蔽?

看一个例子:

var obj1 = {
    name: '前端大杂货铺',
    content: ['前端', '生活']
}

// 赋值
var obj2 = obj1

obj2.name = 'Gping'
obj2.content[2] = '感悟'
console.log(obj1, obj2)
复制代码

var obj1 = {
    name: '前端大杂货铺',
    content: ['前端', '生活']
}

// Object.assign 是浅拷贝
var obj3 = Object.assign({}, obj1)
obj3.name = 'Gping'
obj3.content[2] = '感悟'
console.log(obj1, obj3)
复制代码

obj1 是源对象,obj2 是赋值得到的,obj3 是浅复制得到的,如果我们改变的第一层数据不管是原始类型还是引用类型,那么 obj2 的改变都会导致 obj1 的改变。

obj3 如果第一层数据改变的是原始类型,那么不会影响源数据,改变的是引用类型数据,则会影响 obj1 的改变。

关于赋值,还有一个很基础的点,很惭愧,之前竟然理解错了。上代码

var a = {};
b = a;
b = {};  // 这里 b 已经指向了新的地址,和 a 已经没有任何关系了。跟new Object()应该是一样的
a.name = 'Gping';
console.log(b);  // {}
复制代码

个人理解,通过对象表达式的方式创建一个对象,就已经指向新的地址的,也就是跟之前指向的地址已经没有关系了

总结

赋值和浅拷贝的区别在于对象第一层数据对原对象的影响,如果是赋值,改变会直接影响原对象。如果是浅拷贝,而且属性值是基础类型的话,就不会影响原对象。属性值为引用类型,就会影响原对象

欢迎大家来我杂货铺逛逛,不买东西都行,我们就聊聊天,谈谈心~

欢迎大家关注我的前端大杂货铺

参考:

浅拷贝与深拷贝