📅  最后修改于: 2023-12-03 14:53:00.093000             🧑  作者: Mango
在 JavaScript 中,变量在赋值时有两种方式:值复制和引用。值复制是指将变量的值复制给另一个变量,这两个变量互不影响。引用是只复制变量的指针或地址,这样两个变量指向同一段内存,修改其中一个变量的值会影响另一个变量。
当我们需要复制值时,如果使用“=”赋值,会发生引用,两个变量会指向同一个内存地址。这样会导致一些意外的问题,比如修改副本的值也会修改原本的值。为了避免这些问题,我们可以使用以下方法复制值而不是引用。
如果要复制一个数组,可以使用 slice()
方法。这个方法会返回一个新数组,这个新数组的值和原数组的值相同,但是它们在内存中的地址不同。
let arr1 = [1, 2, 3];
let arr2 = arr1.slice();
arr2[0] = 4;
console.log(arr1); // [1, 2, 3]
console.log(arr2); // [4, 2, 3]
如果要复制一个对象,可以使用 Object.assign()
方法。这个方法会将一个或多个源对象的值复制到目标对象中,然后返回目标对象。如果目标对象不存在,会创建一个空对象。
let obj1 = { a: 1, b: 2 };
let obj2 = Object.assign({}, obj1);
obj2.a = 3;
console.log(obj1); // { a: 1, b: 2 }
console.log(obj2); // { a: 3, b: 2 }
如果要复制一个复杂的对象,比如一个对象数组,可以使用 JSON.parse()
和 JSON.stringify()
方法。这个方法会将一个 JavaScript 对象转换成一个 JSON 字符串,或将一个 JSON 字符串转换成一个 JavaScript 对象。
let arr1 = [{ a: 1, b: 2 }, { c: 3, d: 4 }];
let arr2 = JSON.parse(JSON.stringify(arr1));
arr2[0].a = 5;
console.log(arr1); // [{ a: 1, b: 2 }, { c: 3, d: 4 }]
console.log(arr2); // [{ a: 5, b: 2 }, { c: 3, d: 4 }]
需要注意的是,这个方法会将一些特殊的对象,比如函数、正则表达式以及 undefined 转换成 null。在转换后,执行后续操作时需要注意此类对象的处理。
如果要复制一个对象,可以使用 ES6 的扩展语法。这个方法会将一个对象的所有属性和方法复制到另一个对象中,如果目标对象存在相同的属性或方法,会覆盖原本的属性或方法。
let obj1 = { a: 1, b: 2 };
let obj2 = { ...obj1 };
obj2.a = 3;
console.log(obj1); // { a: 1, b: 2 }
console.log(obj2); // { a: 3, b: 2 }
需要注意的是,这个方法只能复制对象的 own enumerable 属性,无法复制对象原型链上的属性。如果需要复制原型链上的属性,请使用 Object.assign()
方法。
以上是 JavaScript 中复制值而不是引用的几种方法,根据不同的应用场景,选择合适的方法可以极大提高代码的可读性和可维护性。