JS 对象的深拷贝

原文章地址      https://blog.csdn.net/zuggs_/article/details/84784933

callee          https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments/callee

   

代码如下:

let obj = { name: '123', a: { l: 122 }, go: () => { console.log('哇哈哈') } } // let obj2 = Object.assign({}, obj) // let obj2 = Object.JSON.parse(JSON.stringify(obj)) // let obj2 = $.extend({}, obj) let obj2 = clone(obj) obj.go = () => { console.log('握手说') } obj.a.l = 5984654 console.log(obj) console.log(obj2) console.log(obj.go) console.log(obj2.go)

 

 

 1.Object.assign({},obj)       浅拷贝   function拷贝成功 深层对象无法拷贝  obj.a为浅拷贝

 

2.JSON.parse(JSON.stringify(obj))   浅拷贝  function无法拷贝

 

 

3.  jquery   $.extend({}, obj)   浅拷贝  效果等同Object.assign

 

 

 4.完美拷贝  封装的clone

 

function clone (obj) { 
    if(obj === null) return null 
    if(typeof obj !== 'object') return obj;
    if(obj.constructor===Date) return new Date(obj); 
    var newObj = new obj.constructor ();  //保持继承链
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {   //不遍历其原型链上的属性
            var val = obj[key];
    
            // 使用arguments.callee解除与函数名的耦合   (ES5废弃)
            //  newObj[key] = typeof val === 'object' ? arguments.callee(val) :val; 
          newObj[key] = typeof val === 'object' ? clone(val) :val; 
        }
    }  
    return newObj;  
}; 


这种方法也就使封装最好的深拷贝的方法,以下为解释:

1、用new obj.constructor ()构造函数新建一个空的对象,而不是使用{}或者[],这样可以保持原形链的继承;
2、用obj.hasOwnProperty(key)来判断属性是否来自原型链上,因为for..in..也会遍历其原型链上的可枚举属性。
3、上面的函数用到递归算法,在函数有名字,而且名字以后也不会变的情况下,这样定义没有问题。但问题是这个函数的执行与函数名 factorial 紧紧耦合在了一起。为了消除这种紧密耦合的现象,需要使用 arguments.callee(ES5废弃)。 

 

posted @ 2020-07-20 21:41  酒北  阅读(128)  评论(0编辑  收藏  举报