浅拷贝
只复制了引用,没有复制真正的值;
- 实现数组浅拷贝可以利用arr.concat()、arr.slice()、或es6的arr2 = [...arr1];eg:
var arr1 = [{ a: 0, b: { a: 'a' } }, 1, 2];
// var arr2 = arr1.concat();
// var arr2 = arr1.slice();
var arr2 = [...arr1]
arr2[0].a = 'a'
arr2[0].b.a = 111;
arr2[1] = 5
console.log(arr1); //[{"a":"a","b":{"a":111}},1,2]
console.log(arr2); //[{"a":"a","b":{"a":111}},5,2]
-
Object.assign()方法用于将所有可枚举属性的值从一个或多个源sources对象复制到目标对象target。它将返回目标对象。属性被后续参数中具有相同属性的其他对象覆盖.
Object.assign(target, ...sources)
var obj1 = { a: 1, b: { b1: 1 } }
var obj2 = { a: 2, c: 2, d: { d1: 2 } }
var obj3 = { a: 3, e: { e1: 3 } }
var obj4 = Object.assign(obj1, obj2, obj3);
console.log(obj1) // { a: 3, b: { b1: 1 }, c: 2, d: { d1: 2 }, e: { e1: 3 } }
console.log(obj2) // { a: 2, c: 2, d: { d1: 2 } }
console.log(obj3) // { a: 3, e: { e1: 3 } }
console.log(obj4) // { a: 3, b: { b1: 1 }, c: 2, d: { d1: 2 }, e: { e1: 3 } }
obj2.d.d1 = 5;
console.log(obj1) // { a: 3, b: { b1: 1 }, c: 2, d: { d1: 5 }, e: { e1: 3 } }
console.log(obj4) // { a: 3, b: { b1: 1 }, c: 2, d: { d1: 5 }, e: { e1: 3 } }
- 也可以自己实现:
//实现浅拷贝
function shallowCopy(target) {
if (typeof target !== 'object') return
//判断目标类型,来创建返回值
var newData = target instanceof Array ? [] : {};
for (var item in target) {
//只复制元素自身的属性,不复制原型链上的
if (target.hasOwnProperty(item)) {
newData[item] = target[item];
}
}
return newData;
}
var arr1 = [{ a: 0, b: { a: 'a' } }, 1, 2];
var arr2 = shallowCopy(arr1)
arr2[0].a = 'a'
arr2[0].b.a = 111;
arr2[1] = 5
console.log(arr1); //[{"a":"a","b":{"a":111}},1,2]
console.log(arr2); //[{"a":"a","b":{"a":111}},5,2]
深拷贝
复制了真正的值;
- arr2 = JSON.parse(JSON.stringify(arr1));
不适用于值为undefined或function的属性。
如果有一个值为Date类型,拷贝后得到等是时间的字符串。
- 利用递归实现
var deepCopy = (function f(target) {
// 将目标转换为字符串来判断类型,null转换为"[object Null]",
// new Date():"[object Date]",数值:"[object Number]",字符串:"[object String]"等
const type = Object.prototype.toString.call(target);
let newData = type == '[object Object]' ? {} : (type == '[object Array]' ? [] : false)
if(!newData) return target
for (var item in target) {
//只复制元素自身的属性,不复制原型链上的
if (target.hasOwnProperty(item)) {
newData[item] = f(target[item]);
}
}
return newData;
})
var arr1 = [{ a: 0, b: { a: 'a' } }, 1, 2];
var arr2 = deepCopy(arr1)
arr2[0].a = 'a'
arr2[0].b.a = 111;
arr2[1] = 5
console.log(arr1); //[{ a: 0, b: { a: 'a' } }, 1, 2]
console.log(arr2); //[{"a":"a","b":{"a":111}},5,2]