javascript中的浅拷贝和深拷贝

简介: 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后只是说这个对象的引用不能改变了,并不意味着对象的属性不可以改变

相关文章
|
1月前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
45 4
|
2月前
|
JSON JavaScript 数据格式
手写JS实现深拷贝函数
本文介绍了如何实现一个深拷贝函数`deepClone`,该函数可以处理对象和数组的深拷贝,确保拷贝后的对象与原始对象在内存中互不干扰。通过递归处理对象的键值对和数组的元素,实现了深度复制,同时保留了函数类型的值和基础类型的值。
22 3
|
3月前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
40 2
|
3月前
|
JavaScript 前端开发
JavaScript中的深拷贝和浅拷贝的实现讲解
在JavaScript中,浅拷贝与深拷贝用于复制对象。浅拷贝仅复制基本类型属性,对于引用类型仅复制引用,导致双方共享同一数据,一方修改会影响另一方。深拷贝则完全复制所有层级的数据,包括引用类型,确保双方独立。浅拷贝可通过简单属性赋值实现,而深拷贝需递归复制各层属性以避免共享数据。
62 1
|
3月前
|
JavaScript 前端开发
js中浅拷贝和深拷贝的区别
js中浅拷贝和深拷贝的区别
28 0
|
3月前
|
JavaScript 前端开发
js中浅拷贝,深拷贝的实现
js中浅拷贝,深拷贝的实现
33 0
|
3月前
|
存储 JavaScript 前端开发
JS浅拷贝及面试时手写源码
JS浅拷贝及面试时手写源码
|
4月前
|
存储 JavaScript 前端开发
js【详解】数据类型原理(含变量赋值详解-浅拷贝)
js【详解】数据类型原理(含变量赋值详解-浅拷贝)
35 0
|
4月前
|
JavaScript
js【详解】深拷贝 (含 JSON.parse(JSON.stringify(obj)) 的缺陷,5种手写深拷贝)
js【详解】深拷贝 (含 JSON.parse(JSON.stringify(obj)) 的缺陷,5种手写深拷贝)
148 0
|
6月前
|
JSON 前端开发 JavaScript
【面试题】JavaScript 深拷贝和浅拷贝 高级
【面试题】JavaScript 深拷贝和浅拷贝 高级