JavaScript 中复制对象的 3 种方法

摘要:在本教程中,您将学习如何在 JavaScript 中复制对象,包括浅拷贝和深拷贝。 要在 JavaScript 中复制对象,您有三种选择

  1. 使用扩展运算符 (...) 语法
  2. 使用 Object.assign() 方法
  3. 使用 JSON.stringify()JSON.parse() 方法

以下说明了如何使用上面三种方法复制对象

const person = {
    firstName: 'John',
    lastName: 'Doe'
};


// using spread ...
let p1 = {
    ...person
};

// using  Object.assign() method
let p2 = Object.assign({}, person);

// using JSON
let p3 = JSON.parse(JSON.stringify(person));
Code language: JavaScript (javascript)

扩展运算符 (...) 和 Object.assign() 都执行浅拷贝,而 JSON 方法执行深拷贝。

浅拷贝 vs 深拷贝

在 JavaScript 中,您使用 变量 来存储可以是 原始值或引用 的值。 当您复制存储在变量中的值时,您会创建一个具有相同值的新的变量。 对于原始值,您只需使用简单的赋值

let counter = 1;
let copiedCounter = counter;
Code language: JavaScript (javascript)

当您更改复制变量的值时,原始变量的值保持不变。

copiedCounter = 2;
console.log(counter); 
Code language: JavaScript (javascript)

输出

1

但是,如果您对引用值使用赋值运算符,它不会复制该值。 相反,这两个变量将引用内存中的同一个对象

let person = {
    firstName: 'John',
    lastName: 'Doe'
};
let copiedPerson = person;Code language: JavaScript (javascript)

当您通过新变量 (copiedPerson) 访问对象并更改其属性 (name) 的值时,您会更改对象的属性的值。

copiedPerson.firstName = 'Jane';
console.log(person); 
Code language: JavaScript (javascript)

输出

{
    firstName: 'Jane',
    lastName: 'Doe'
}Code language: CSS (css)

深拷贝意味着新变量的值与原始变量断开连接,而浅拷贝意味着某些值仍与原始变量连接。

浅拷贝示例

考虑以下示例

let person = {
    firstName: 'John',
    lastName: 'Doe',
    address: {
        street: 'North 1st street',
        city: 'San Jose',
        state: 'CA',
        country: 'USA'
    }
};


let copiedPerson = Object.assign({}, person);

copiedPerson.firstName = 'Jane'; // disconnected

copiedPerson.address.street = 'Amphitheatre Parkway'; // connected
copiedPerson.address.city = 'Mountain View'; // connected

console.log(copiedPerson);
Code language: JavaScript (javascript)

在本例中

  • 首先,创建一个名为 person 的新对象。
  • 其次,使用 Object.assign() 方法克隆 person 对象。
  • 第三,更改 copiedPerson 对象的姓氏和地址信息。

这是输出

{
    firstName: 'Jane',
    lastName: 'Doe',
    address: {
        street: 'Amphitheatre Parkway',
        city: 'Mountain View',
        state: 'CA',
        country: 'USA'
    }
}
Code language: CSS (css)

但是,当您显示 person 对象的值时,您会发现地址信息已更改,但姓氏

console.log(person);
Code language: JavaScript (javascript)

输出

{
    firstName: 'John',
    lastName: 'Doe',
    address: {
        street: 'Amphitheatre Parkway',
        city: 'Mountain View',
        state: 'CA',
        country: 'USA'
    }
}
Code language: CSS (css)

原因是地址是引用值,而姓氏是原始值。 personcopiedPerson 引用不同的对象,但这些对象引用相同的 address 对象。

深拷贝示例

以下代码段用 JSON 方法替换 Object.assign() 方法来执行 person 对象的深拷贝

let person = {
    firstName: 'John',
    lastName: 'Doe',
    address: {
        street: 'North 1st street',
        city: 'San Jose',
        state: 'CA',
        country: 'USA'
    }
};


let copiedPerson = JSON.parse(JSON.stringify(person));

copiedPerson.firstName = 'Jane'; // disconnected

copiedPerson.address.street = 'Amphitheatre Parkway';
copiedPerson.address.city = 'Mountain View';

console.log(person);
Code language: JavaScript (javascript)

输出

{
    firstName: 'John',
    lastName: 'Doe',
    address: {
        street: 'North 1st street',
        city: 'San Jose',
        state: 'CA',
        country: 'USA'
    }
}
Code language: CSS (css)

在本例中,copiedPerson 对象中的所有值都与原始 person 对象断开连接。 在本教程中,您已经了解了如何使用浅拷贝或深拷贝在 JavaScript 中复制对象。

本教程是否有帮助?