浅拷贝的实现
什么是浅拷贝?
浅拷贝是指将一个新的对象对原始对象的属性值进行精确地拷贝,如果是基本数据类型,拷贝的就是基本数据类型的值,如果是引用数据类型,拷贝的就是内存地址。如果其中一个对象的引用类型属性的值发生改变,另一个对象也会发生变化。
代码实现
通常情况下,有多种手段可以实现浅拷贝
Object.assign()
Object.assign() 是 ES6 中对象的拷贝方法,第一个参数是要拷贝到的目标对象,其余参数是源对象。
用法:Object.assign(target, source_1, ···)
TIP
- 如果目标对象和源对象有同名属性,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性。
- 当该函数只有一个参数是,如果参数为对象,直接返回该对象;如果参数不是对象,会先将参数转为对象然后返回。
- 因为 null 和 undefined 不能转化为对象,所以第一个参数不能为 null 或 undefined,会报错。
js
let target = {a: 1}
let object2 = {b: 2};
let object3 = {c: 3};
Object.assign(target,object2,object3);
console.log(target); // {a: 1, b: 2, c: 3}扩展运算符
在构造字面量对象时,可以使用扩展运算符进行对象属性的拷贝。
用法:let cloneObj = {...obj}
js
let obj1 = {a:1,b:{c:1}}
let obj2 = {...obj1};
obj1.a = 2;
console.log(obj1); //{a:2,b:{c:1}}
console.log(obj2); //{a:1,b:{c:1}}
obj1.b.c = 2;
console.log(obj1); //{a:2,b:{c:2}}
console.log(obj2); //{a:1,b:{c:2}}数组方法实现数组浅拷贝
Array.prototype.slice()
slice()方法可以从已有的数组中返回选定的元素,该方法不会改变原数组。- 该方法有两个参数,两个参数都可选,如果两个参数都不写,就可以实现一个数组的浅拷贝。
用法:Array.slice(start, end)
js
let arr = [1, 2, 3, 4]
console.log(arr.slice()); // [1,2,3,4]
console.log(arr.slice() === arr); //falseArray.prototype.concat()
concat()方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。- 该方法有两个参数,两个参数都可选,如果两个参数都不写,就可以实现一个数组的浅拷贝。
用法: arr1.concat(arr2)
js
let arr = [1,2,3,4];
console.log(arr.concat()); // [1,2,3,4]
console.log(arr.concat() === arr); //false手写实现
js
// 浅拷贝的实现;
function shallowCopy(object) {
// 只拷贝对象
if (!object || typeof object !== "object") return;
// 根据 object 的类型判断是新建一个数组还是对象
let newObject = Array.isArray(object) ? [] : {};
// 遍历 object,并且判断是 object 的属性才拷贝
for (let key in object) {
if (object.hasOwnProperty(key)) {
newObject[key] = object[key];
}
}
return newObject;
}// 浅拷贝的实现;
function shallowCopy(object) {
// 只拷贝对象
if (!object || typeof object !== "object") return;
// 根据 object 的类型判断是新建一个数组还是对象
let newObject = Array.isArray(object) ? [] : {};
// 遍历 object,并且判断是 object 的属性才拷贝
for (let key in object) {
if (object.hasOwnProperty(key)) {
newObject[key] = object[key];
}
}
return newObject;
}// 浅拷贝的实现;
function shallowCopy(object) {
// 只拷贝对象
if (!object || typeof object !== "object") return;
// 根据 object 的类型判断是新建一个数组还是对象
let newObject = Array.isArray(object) ? [] : {};
// 遍历 object,并且判断是 object 的属性才拷贝
for (let key in object) {
if (object.hasOwnProperty(key)) {
newObject[key] = object[key];
}
}
return newObject;
}
Blog of Desain