欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

如何实现JavaScript的深拷贝

程序员文章站 2022-07-07 19:43:11
如何通过自定义的deepclone,实现对对象,数组的深拷贝。 ......

在JavaScript中,对于引用类型来说,想要实现对一个对象的修改而不改变原来本身的对象,就需要对对象就行拷贝,拷贝分为深浅拷贝,如果一个对象或者一个数组中的value都是基本类型的话,那么通过浅拷贝就可以将一个对象复制,并且修改属性不会影响原来的对象,js中基本类型包括5种,分别是 String,Number,Boolean,Null,Undefined五种类型,也就是说如果你的引用类型中只有这5种类型的话,那么你只需要通过浅拷贝就可以实现。

var newobj = Object.assign({},obj);

  但是对于一些复杂的类型,仅仅通过Object.assign来说就显得不是那么够了。ok,这里有两种方式可以实现,第一种,我们可以通过自己实现的一个deepclone来实现深拷贝

function deepclone(obj) {
    let newobj = Array.isArray(obj) ? [] : {}; //在这里判断传入的类型然后初始化一个空的对象或数组
    for(let key in obj){
        let type = Object.prototype.toString.call(obj[key]);//判断对象属性的类型,如果为引用类型递归处理
        if( type === '[object Array]' || type === '[object Object]'){
            newobj[key] = deepclone(obj[key]);
        }
        else{
            newobj[key] = obj[key];
        }
    }
    return newobj;
}

  

  通过这种方法我们就实现了一个对象的深拷贝,下面是测试的结果

var test = {
    score: [1,[3,4,5],3],
    name: 'petter',
    skill: {
        run: function () {
            console.log('I can run fast');
        } 
    }
} 

var mytest = deepclone(test);

mytest.name = 'jenny';

console.log('Myname is ' + test.name);

mytest.score[1].push(4);

console.log(mytest.score);

console.log(test.score);

mytest.skill.run = function () {
    console.log('I can\'t run fast');
}

test.skill.run();

mytest.skill.run();

{ score: [ 1, [ 3, 4, 5 ], 3 ],
  name: 'petter',
  skill: { run: [Function: run] } }
Myname is petter
[ 1, [ 3, 4, 5, 4 ], 3 ]
[ 1, [ 3, 4, 5 ], 3 ]
I can run fast
I can't run fast

  还有一种深拷贝的实现方法是通过json,当然这有点黑科技了

var newobj = JSON.parse(JSON.stringify(obj));

  这种方法的缺点是对象的方法会丢失,因为对于JSON格式的数据来说是不应该有function的,所以在JSON.stringify中会帮我们将这些方法给滤掉,也就会造成丢失。

所以使用时应该多加小心。

ok,今天的总结就到这。