深入浅出讲解拷贝
2023-12-30 09:31:22
一、拷贝的本质
拷贝,本质上是一种复制行为,将一个变量中的值复制到另一个变量中。拷贝通常是为了保存数据的副本,以便在需要时使用。
二、基本数据类型与对象数据类型的拷贝
基本数据类型的数据,如字符串、数字和布尔值,在拷贝时,会被直接复制到另一个变量中。例如:
let name = "John";
let copyName = name;
在上面的代码中,copyName
变量的值等于name
变量的值。如果name
变量的值发生改变,copyName
变量的值也不会改变。这是因为基本数据类型的数据在内存中是按值存储的。
对象数据类型的数据,如数组、对象和函数,在拷贝时,不会被直接复制到另一个变量中。相反,另一个变量会存储对该对象的引用。例如:
let person = {
name: "John",
age: 30
};
let copyPerson = person;
在上面的代码中,copyPerson
变量的值等于对person
对象的引用。如果person
对象的值发生改变,copyPerson
对象的值也会改变。这是因为对象数据类型的数据在内存中是按引用存储的。
三、浅拷贝与深拷贝
浅拷贝是一种只拷贝对象的第一层属性的拷贝方式。这意味着浅拷贝只会拷贝对象本身的属性,而不会拷贝对象引用的其他对象。例如:
let person = {
name: "John",
age: 30,
address: {
city: "New York",
state: "NY"
}
};
let copyPerson = Object.assign({}, person);
在上面的代码中,copyPerson
变量的值是person
对象的浅拷贝。copyPerson
变量具有name
和age
属性,但没有address
属性。这是因为address
属性是一个对象,浅拷贝不会拷贝对象引用的其他对象。
深拷贝是一种拷贝对象的所有属性的拷贝方式。这意味着深拷贝不仅会拷贝对象本身的属性,还会拷贝对象引用的其他对象。例如:
let person = {
name: "John",
age: 30,
address: {
city: "New York",
state: "NY"
}
};
let copyPerson = JSON.parse(JSON.stringify(person));
在上面的代码中,copyPerson
变量的值是person
对象的深拷贝。copyPerson
变量具有name
、age
和address
属性。这是因为深拷贝会拷贝对象的所有属性,包括对象引用的其他对象。
四、JavaScript中的特殊场景——引用类型拷贝
JavaScript中,引用类型的数据,如数组和对象,在拷贝时,实际上是拷贝了对该对象的引用。这意味着,如果两个变量都指向同一个对象,那么这两个变量的值就是相同的。例如:
let person = {
name: "John",
age: 30
};
let copyPerson = person;
person.name = "Bob";
console.log(copyPerson.name); // "Bob"
在上面的代码中,copyPerson
变量的值等于对person
对象的引用。当person
对象的值发生改变时,copyPerson
对象的值也会改变。这是因为两个变量都指向同一个对象。
如果要创建一个新的对象,而不是拷贝一个对象的引用,可以使用Object.assign()
方法或JSON.parse(JSON.stringify())
方法。例如:
let person = {
name: "John",
age: 30
};
let copyPerson = Object.assign({}, person);
person.name = "Bob";
console.log(copyPerson.name); // "John"
在上面的代码中,copyPerson
变量的值是person
对象的浅拷贝。copyPerson
变量具有name
和age
属性,但没有address
属性。这是因为address
属性是一个对象,浅拷贝不会拷贝对象引用的其他对象。
let person = {
name: "John",
age: 30
};
let copyPerson = JSON.parse(JSON.stringify(person));
person.name = "Bob";
console.log(copyPerson.name); // "John"
在上面的代码中,copyPerson
变量的值是person
对象的深拷贝。copyPerson
变量具有name
、age
和address
属性。这是因为深拷贝会拷贝对象的所有属性,包括对象引用的其他对象。