答: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


 

 

 

 

 

 

 

 

 

posted on 2021-02-21 21:54  ygunoil  阅读(134)  评论(0编辑  收藏  举报