数字化转型|广州蓝景分享—谈谈JavaScript 的对象复制

数字化转型|广州蓝景分享—谈谈JavaScript 的对象复制


Hello~~各位小伙伴 , 今天小编与大家分享JavaScript的对象复制 。
对象是JavaScript的基本块 。 对象是属性的集合 , 属性是键(或名称)和值之间的关联 。 JavaScript中几乎所有的对象都是位于原型链顶部的Object的实例 。
简介
我们知道 , 赋值运算符不会创建一个对象的副本 , 它只分配一个引用 , 请看以下代码:
let obj = {
a: 1
b: 2
;
let copy = obj;
obj.a = 5;
console.log(copy.a);
// Result
// a = 5;
obj变量是初始化的新对象的容器 。 copy变量指向同一个对象 , 并且是该对象的引用 。 所以基本上这个{ a: 1 b: 2 对象是在说现在有两种方法可以访问我:通过obj变量或copy变量以任何一种方式传递给我 , 并且你通过这些方式对我所做的任何操作都会影响我 。
此方法消除了任何形式的不变性 , 如果原始对象被代码的另一部分使用 , 可能会导致bug 。
复制对象的简单方法
复制对象的简单方法是遍历原始对象并一个接一个地复制每个属性 。 让我们看一下这段代码:
function copy(mainObj) {
let objCopy = {; // objCopy will store a copy of the mainObj
let key;
for (key in mainObj) {
objCopy[key
= mainObj[key
; // copies each property to the objCopy object

return objCopy;

const mainObj = {
a: 2
b: 5
c: {
x: 7
y: 4


console.log(copy(mainObj));
存在的问题:

  1. objCopy对象有一个新的Object.prototype方法 , 不同于mainObj对象的原型方法 , 这不是我们想要的 。 我们想要的是原始对象的精确副本 。
  2. 不复制属性描述符 。 值设置为false的“可写”描述符在objCopy对象中将为true 。
  3. 上面的代码只复制了mainObj的可枚举属性 。
  4. 如果原始对象中的属性之一是对象本身 , 那么它将在副本和原始对象之间共享 , 使它们各自的属性指向同一个对象 。
浅拷贝对象
当源顶层属性在没有任何引用的情况下被复制并且存在一个值为对象并被复制为引用的源属性时 , 就称该对象为浅拷贝 。 如果源值是对对象的引用 , 那么它只会将该引用值复制到目标对象 。
浅拷贝将复制顶层属性 , 但嵌套对象在原始(源)和副本(目标)之间共享 。
使用Object.assign()方法
Object.assign()方法用于将所有可枚举自身属性的值从一个或多个源对象复制到目标对象 。
let obj = {
a: 1
b: 2
;
let objCopy = Object.assign({ obj);
console.log(objCopy);
// Result - { a: 1 b: 2
到目前为止 , 我们创建了一个obj的副本 。 现在让我们看看是否存在不可变性:
let obj = {
a: 1
b: 2
;
let objCopy = Object.assign({ obj);
console.log(objCopy); // result - { a: 1 b: 2
objCopy.b = 89;
console.log(objCopy); // result - { a: 1 b: 89
console.log(obj); // result - { a: 1 b: 2
上面的代码将objCopy对象中的属性b的值更改为89 , 当我们在控制台中记录修改后的objCopy对象时 , 更改仅应用于objCopy 。 最后一行代码检查obj对象是否仍然完整且未曾更改 。 如果是的话 , 意味着我们已经成功地创建了源对象的副本 , 而没有对其进行任何引用 。
Object.assign()的陷阱
虽然我们成功创建了副本 , 并且一切似乎都运行良好 , 但还记得我们讨论过浅拷贝吗?看一个例子:
let obj = {
a: 1
b: {
c: 2


let newObj = Object.assign({ obj);