zoukankan      html  css  js  c++  java
  • 深拷贝与浅拷贝的区别(深合并)

    答: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 (items) {  
            let item = Object.getOwnPropertyDescriptor(obj, items);  
            Object.defineProperty(copy, items, item);    
        });  
        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
    


     

     

     

     

     

  • 相关阅读:
    HTML表格和列表笔记&练习<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>关于表格的一些练习</title> </head> <body> <p>一个普通基本的表格</p> <table border="5&
    HTML中的CSS类型
    html关于图片和链接的笔记
    实现窗体背景透明
    HTML控件篇 -- input
    AngularJs的$http使用随笔
    Win7启动修复(Ubuntu删除后进入grub rescue的情况)
    2013年9月30日我的博客园开通啦
    将excel表格导入到DataGridView
    c#中,点击一个菜单项后调用exe文件
  • 原文地址:https://www.cnblogs.com/ygunoil/p/14427418.html
Copyright © 2011-2022 走看看