浅拷贝:意思就是只复制引用地址(指针),而未复制真正的值 深拷贝:目标的完全拷贝(只要进行了深拷贝,它们老死不相往来,谁也不会影响谁) 深拷贝实现的3种常用的方法:
(1)递归去复制所有层级属性
a.
function deepClone(source) {
const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
for (let keys in source) { // 遍历目标
if (source.hasOwnProperty(keys)) {
if (source[keys] && typeof source[keys] === 'object') { // 如果值是对象,就递归一下
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = deepClone(source[keys]);
} else { // 如果不是,就直接赋值
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
const obj1 = {
name: 'axuebin',
sayHello: function () {
console.log('Hello World');
}
}
const obj2 = deepClone(obj1);
const obj3 = obj1;
console.log(obj2); // {name: "axuebin", sayHello: ƒ}
console.log(obj1 === obj2); // false
console.log(obj1 === obj3); // true*/
b.
function extend(parent) {
let child;
if (Object.prototype.toString.call(parent) == '[object Object]') {
child = {};
for (let key in parent) {
child[key] = extend(parent[key])
}
} else if (Object.prototype.toString.call(parent) == '[object Array]') {
child = parent.map(item => extend(item));
} else {
return parent;
}
return child;
}
function extendDeep(parent, child) {
child = child || {};
for (var key in parent) {
if (typeof parent[key] === "object") {
child[key] = (Object.prototype.toString.call(parent[key]) === "[object Array]") ? [] : {};
extendDeep(parent[key], child[key]);
} else {
child[key] = parent[key];
}
}
return child;
}
var obj1 = {
age: 5,
hobby: [1, 2, 3],
home: {city: '北京'},
};
var obj2 = extendDeep(obj1);
console.log(obj1===obj2);//false
注:slice方法不是真正的深拷贝
let a = [0,1,[2,3],4]
let b = a.slice()
a[0] = 1
a[2][0] = 1 // [1,1,[1,3],4]
b //[0,1,[1,3],4]
深拷贝过后两个是独立的,改变任何一个都不能改变另外一个。
(2)用JSON对象的parse和stringify
const obj3 = {
name:'axuebin',
sayHello:function(){
console.log('Hello World');
}
}
console.log(JSON.parse(JSON.stringify(obj3)); // {name: "axuebin"} ???
// undefined、function、symbol 会在转换过程中被忽略,所以就不能用这个方法进行深拷贝
(3)JQ的extend方法
$.extend([deep ], target, object1 [, objectN ])
// deep表示是否深拷贝,为true为深拷贝;为false,为浅拷贝。
// target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
// object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。
例:
let a = [0,1,[2,3],4]
let b = $.extend(true, [], a)
a[0] = 1
a[2][0] = 1 // [1,1,[1,3],4]
b // [0,1,[2,3],4]