跳到主要内容

JavaScript 程序:克隆一个 JS 对象

要理解这个示例,你应该具备以下 JavaScript 编程 主题的知识:

JavaScript 对象是一种可以包含多种数据类型的复杂数据类型。例如,

const person = {
name: "John",
age: 21,
};

这里,person 是一个对象。现在,你不能通过像这样的操作来克隆一个对象。

const copy = person;
console.log(copy); // {name: "John", age: 21}

在上述程序中,copy 变量与 person 对象有相同的值。然而,如果你更改 copy 对象的值,person 对象中的值也会发生变化。例如,

copy.name = "Peter";
console.log(copy.name); // Peter
console.log(person.name); // Peter

两个对象都发生了变化,因为对象是引用类型copyperson 都指向同一个对象。

示例 1. 使用 Object.assign() 克隆对象

// 程序克隆对象

// 声明对象
const person = {
name: "John",
age: 21,
};

// 克隆对象
const clonePerson = Object.assign({}, person);

console.log(clonePerson);

// 更改 clonePerson 的值
clonePerson.name = "Peter";

console.log(clonePerson.name);
console.log(person.name);

输出

{name: "John", age: 21}
Peter
John

Object.assign() 方法是 ES6 标准的一部分。Object.assign() 方法执行深拷贝,并从一个或多个对象复制所有属性。

注意:第一个参数为空 {} 确保你不会改变原始对象。

示例 2:使用展开语法克隆对象

// 程序克隆对象
// 声明对象
const person = {
name: "John",
age: 21,
};

// 克隆对象
const clonePerson = { ...person };

console.log(clonePerson);

// 更改 clonePerson 的值
clonePerson.name = "Peter";

console.log(clonePerson.name);
console.log(person.name);

输出

{name: "John", age: 21}
Peter
John

展开语法 ... 在后续版本(ES6)中引入。

展开语法可以用来制作对象的浅拷贝。这意味着它会复制对象。然而,更深层次的对象是被引用的。例如,

const person = {
name: "John",
age: 21,

// 浅拷贝中的内部对象将会改变
marks: { math: 66, english: 73 },
};

// 克隆对象
const clonePerson = { ...person };

console.log(clonePerson); // {name: "John", age: 21, marks: {…}}

// 更改 clonePerson 的值
clonePerson.marks.math = 100;

console.log(clonePerson.marks.math); // 100
console.log(person.marks.math); // 100

这里,当 clonePerson 对象的内部对象值 math 改为 100 时,person 对象的 math 键的值也发生了变化。

示例 3:使用 JSON.parse() 克隆对象

// 程序克隆对象
// 声明对象
const person = {
name: "John",
age: 21,
};

// 克隆对象
const clonePerson = JSON.parse(JSON.stringify(person));

console.log(clonePerson);

// 更改 clonePerson 的值
clonePerson.name = "Peter";

console.log(clonePerson.name);
console.log(person.name);

输出

{name: "John", age: 21}
Peter
John

在上述程序中,使用了 JSON.parse() 方法克隆对象。

注意JSON.parse() 只适用于 NumberString 对象字面量。它不适用于带有 functionsymbol 属性的对象字面量。