答:1.深拷贝是复制一个对象出来,改变复制出的对象的值原对象的值不会改变;
浅拷贝复制的是一个对象的指针,改变复制出的对象的值原对象的值也会跟着改变;
2.浅拷贝的方式有四种:
a.直接赋值 b. object.assign c.扩展运算符... d. 数组的concat、slice方法
深拷贝的方法有四种:
a:JSON转换
json.parse(json.stringify(obj))
缺点:(1)如果对象里有函数,函数无法被拷贝下来
(2)无法拷贝copyObj对象原型链上的属性和方法
(3)当数据的层次很深,会栈溢出
b:用for…in实现遍历和复制
function deepClone(obj){
let objClone = Array.isArray(obj)?[]:{};//先判断要拷贝的对象是否是数组,如果是是数组定义一个空数组,如果是对象定义一个空对象
if(obj && typeof obj==="object"){//再判断是否是对象类型
for(key in obj){//遍历对象的每一个属性或数组的每一个值
if(obj.hasOwnProperty(key)){//再判断要拷贝的对象类型是否有该属性
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
let a=[1,2,3,4],
b=deepClone(a);
a[0]=2;
console.log(a,b);
缺点:
(1)互相引用的值会出错
(2)当数据的层次很深,会栈溢出
C.利用数组的Array.prototype.forEach进copy
let deepClone = function (obj) {
let copy = Object.create(Object.getPrototypeOf(obj));
let propNames = Object.getOwnPropertyNames(obj);
propNames.forEach(function (key) {
let value= Object.getOwnPropertyDescriptor(obj, key);
Object.defineProperty(copy, key, value);
});
return copy;
};
let testObj = {
name: "weiqiujuan",
sex: "girl",
age: 22,
favorite: "play",
family: {brother: "wei", mother: "haha", father: "heihei"}
}
let testRes2 = deepClone(testObj);
console.log(testRes2);
d:优点:
(1)不会栈溢出
(2)支持很多层级的数据
function cloneLoop(x) {
const root = {};
// 栈
const loopList = [
{
parent: root,
key: undefined,
data: x,
}
];
while(loopList.length) {
// 深度优先
const node = loopList.pop();
const parent = node.parent;
const key = node.key;
const data = node.data;
// 初始化赋值目标,key为undefined则拷贝到父元素,否则拷贝到子元素
let res = parent;
if (typeof key !== 'undefined') {
res = parent[key] = {};
}
for(let k in data) {
if (data.hasOwnProperty(k)) {
if (typeof data[k] === 'object') {
// 下一次循环
loopList.push({
parent: res,
key: k,
data: data[k],
});
} else {
res[k] = data[k];
}
}
}
}
return root;
}
function copyObject(orig) {
var copy = Object.create(Object.getPrototypeOf(orig));
copyOwnPropertiesFrom(copy, orig);
return copy;
}
function copyOwnPropertiesFrom(target, source) {
Object.getOwnPropertyNames(source).forEach(function (propKey) {
var desc = Object.getOwnPropertyDescriptor(source, propKey);
Object.defineProperty(target, propKey, desc);
});
return target;
}
var obj = {
name: 'Jack',
age: '32',
job: 'developer'
};
var obj2 = copyObject(obj);
console.log(obj2);
obj.age = 39;
obj.name = 'Tom';
console.log(obj);
console.log(obj2);
class Copy {
static deepClone(orig) {
const copy = Object.create(Object.getPrototypeOf(orig));
return this.copyOwnPropertiesFrom(copy, orig);
}
static copyOwnPropertiesFrom(target, source) {
Object.getOwnPropertyNames(source).forEach((propKey) => {
const desc = Object.getOwnPropertyDescriptor(source, propKey);
Object.defineProperty(target, propKey, desc);
});
return target;
}
}
Copy.deepClone(window) // 深拷贝window/this





浙公网安备 33010602011771号