javascript中的浅拷贝和深拷贝
Posted 低代码布道师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript中的浅拷贝和深拷贝相关的知识,希望对你有一定的参考价值。
谈这个话题特指javascript中的对象,我们使用赋值的语法来定义一个对象,其实只是获取了这个对象的引用
let user = {
name: "John"
};
这里的user变量只是指向了对象,是对象的一个引用
如果我们再定义一个变量,并且把user赋值给变量
let user = { name: "John" };
let admin = user; // copy the reference
这里的admin也指向了变量,user和admin都是对象的引用
let user = { name: 'John' };
let admin = user;
admin.name = 'Pete'; // changed by the "admin" reference
alert(user.name); // 'Pete', changes are seen from the "user" reference
因为指向的是一个对象,所以通过admin来改变对象的属性,再用user去访问属性时会得到一个值,是改变后的Pete
let a = {};
let b = a; // copy the reference
alert( a == b ); // true, both variables reference the same object
alert( a === b ); // true
因为a和b都指向相同的对象,所以他们的值和类型都相同
let a = {};
let b = {}; // two independent objects
alert( a == b ); // false
a和b是两个对象,所以他们不相等
变量定义和赋值不能实现对象的拷贝,那我想复制出一模一样的对象怎么办?
let user = {
name: "John",
age: 30
};
let clone = {}; // the new empty object
// let's copy all user properties into it
for (let key in user) {
clone[key] = user[key];
}
// now clone is a fully independent object with the same content
clone.name = "Pete"; // changed the data in it
alert( user.name ); // still John in the original object
可以迭代对象的属性做赋值,但是这样稍显麻烦,javascript有现成的API可以做到这一件事
Object.assign(dest, [src1, src2, src3...])
通过这个API就可以实现将对象的属性进行合并赋值给新的对象
例如:
let user = { name: "John" };
let permissions1 = { canView: true };
let permissions2 = { canEdit: true };
// copies all properties from permissions1 and permissions2 into user
Object.assign(user, permissions1, permissions2);
// now user = { name: "John", canView: true, canEdit: true }
如果要是遇到属性相同会进行覆盖
let user = { name: "John" };
Object.assign(user, { name: "Pete" });
alert(user.name); // now user = { name: "Pete" }
我们也可以采用简写的语法
let user = {
name: "John",
age: 30
};
let clone = Object.assign({}, user);
这样就复制出一个对象来,clone就是复制后的对象
如果对象的属性也是对象,那这种情况复制会出现什么情况呢?
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
alert( user.sizes.height ); // 182
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
let clone = Object.assign({}, user);
alert( user.sizes === clone.sizes ); // true, same object
// user and clone share sizes
user.sizes.width++; // change a property from one place
alert(clone.sizes.width); // 51, see the result from the other one
这样的复制叫浅拷贝,因为只是拷贝了对象的引用,如果原对象的值发生改变会影响到复制出来的新对象的值,这样就造成了混乱。所以当对象的属性也是对象时,使用浅拷贝的API就行不通了,这个时候我们需要使用深拷贝。
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
深拷贝会递归的迭代属性,属于彻底的复制出一个新的对象来。
另外还需注意的就是const
const user = {
name: "John"
};
user.name = "Pete"; // (*)
alert(user.name); // Pete
使用const后只是说这个对象的引用不能改变了,并不意味着对象的属性不可以改变
以上是关于javascript中的浅拷贝和深拷贝的主要内容,如果未能解决你的问题,请参考以下文章