• 深拷贝


    JS实现深拷贝

    //注 转载于https://www.cnblogs.com/dobeco/p/11295316.html

    一、赋值、浅拷贝与深拷贝的区别

    二、深拷贝的方法

    1.JSON转换

    1 var targetObj = JSON.parse(JSON.stringify(copyObj))
    2 let arr4 = JSON.parse(JSON.stringify(arr))

    缺点:

    (1)如果对象里有函数,函数无法被拷贝下来

    (2)无法拷贝copyObj对象原型链上的属性和方法

    (3)当数据的层次很深,会栈溢出

    2.普通递归函数 

    (1)如果对象里有函数,函数无法被拷贝下来

    (2)无法拷贝copyObj对象原型链上的属性和方法

    (3)当数据的层次很深,会栈溢出

    2.普通递归函数

    function deepCopy( source ) {
    if (!isObject(source)) return source; //如果不是对象的话直接返回
        let target = Array.isArray( source ) ? [] : {} //数组兼容
        for ( var k in source ) {
            if (source.hasOwnProperty(k)) {
                if ( typeof source[ k ] === 'object' ) {
                    target[ k ] = deepCopy( source[ k ] )
                } else {
                    target[ k ] = source[ k ]
                }
            }
        }
        return target
    }
    
    function isObject(obj) {
        return typeof obj === 'object' && obj !== null
    }

    缺点:

    (1)无法保持引用

    (2)当数据的层次很深,会栈溢出

    3.防栈溢出函数

    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;
    }

    优点:

    (1)不会栈溢出

    (2)支持很多层级的数据

    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);
  • 相关阅读:
    win7破解vs2008
    学习C# via clr 第三版扎记
    html 网页嵌入 QQ MSN 旺旺 Gtalk快速对话框官方代码的方法
    识别打气筒气嘴 法式气嘴、美式气嘴、英式气嘴
    飞信资料
    DCOM 遇到错误 “登录失败:未知的用户名或错误密码
    VS 新建Asp.Net 网站 与 新建Asp.Net web 应用程序区别
    一款网页开发必备,让你欲罢不能的客户网页编辑js控件 百度 UEditor
    一天一小步_我学C#入门精典_第一天
    将DataTable对象输出到新建EXCEL文档中
  • 原文地址:https://www.cnblogs.com/muouran/p/13746198.html
Copyright © 2020-2023  润新知