美文网首页
JavaScript - 深浅拷贝Object.assign()

JavaScript - 深浅拷贝Object.assign()

作者: 小棋子js | 来源:发表于2020-03-17 10:25 被阅读0次

引入:值类型存储在栈内存中,引用类型存储在堆内存,深浅拷贝主要是针对引用类型来说的(数组、对象等)。(值类型直接赋值就能开辟新存储空间,引用类型直接赋值得到的是引用,实际还是同一个空间)

一.浅拷贝:复制的只是引用,原对象属性的改变会引起拷贝对象对应引用属性的变化。

方法1:遍历并复制(只能拷贝第一层)

function simpleCopy(obj){
    const targetObj = Object.prototype.toString.call(obj) == '[object Array]'?[]:{};
    for(let key in obj){
        targetObj[key] = obj[key];
    }
    return targetObj;
}
let a = {
    name:'tom',
    age:20,
    friends:{
        student:['jack']
    }
}
let b = simpleCopy(a);
a.friends.student = ['tony'];
console.log(a);// { name: 'tom', age: 20, friends: { student: [ 'tony' ] } }
console.log(b);// { name: 'tom', age: 20, friends: { student: [ 'tony' ] } }

方法2.使用Object.assign()(只能拷贝第一层)

let a = {
    name:'tom',
    age:20,
    friends:{
        student:['jack']
    }
}
let b = Object.assign({},a);
a.friends.student = ['tony'];
console.log(a);// { name: 'tom', age: 20, friends: { student: [ 'tony' ] } }
console.log(b);// { name: 'tom', age: 20, friends: { student: [ 'tony' ] } }

二.深拷贝:开辟新的内存空间,原对象与拷贝对象之间没有影响。

方法1:使用JSON.parse()加JSON.stringify()

let obj = {
  name:'tom',
  age:10,
  friend:{
    name:'jack'
  }
};
let copy = JSON.parse(JSON.stringify(obj));
obj.name = 'elric';
console.log(obj);// {name: "elric", age: 10, friend: {…}}
console.log(copy);// {name: "tom", age: 10, friend: {…}}

copy对象的name没有因为obj的name变化而变化,说明该方法实现了深拷贝。缺陷:无法拷贝函数、undefined

方法2:递归层层拷贝,直到基本值类型为止。

function deepCopy(obj){
    // 判断是否为引用类型
    if(!obj && typeof obj !== 'object'){
        throw new Error('type error');
    }
    const targetObj = Object.prototype.toString.call(obj) == '[object Array]'?[]:{};
    for(let key in obj){
        let prop = obj[key]; // 避免相互引用造成死循环,如obj.a=obj
        if (prop == obj) {
          continue;
        }
        // 只有对象本身的属性才复制
        if(obj.hasOwnProperty(key)){
            // 如果是引用类型继续向下
            if(obj[key] && typeof obj[key] == 'object'){
                targetObj[key] = deepCopy(obj[key]);
            }else{
                targetObj[key] = obj[key];
            }
        }
    }
    return targetObj;
}
let a = {
    name:'tom',
    age:undefined,
    friends:['tom','jack','merry'],
    sayName(){
        console.log(this.name);
    }
}
let b = deepCopy(a);
a.age = 20;
a.name = 'tony';
console.log(a);
console.log(b);
b.sayName();

相关文章

  • JavaScript - 深浅拷贝Object.assign()

    引入:值类型存储在栈内存中,引用类型存储在堆内存,深浅拷贝主要是针对引用类型来说的(数组、对象等)。(值类型直接赋...

  • js 手写深浅拷贝

    实现深浅拷贝 浅拷贝 先说一下浅拷贝的实现方式 Object.assign() ES6 中 Object 的一方法...

  • javascript深浅拷贝

    Javascript有六种基本数据类型(也就是简单数据类型),它们分别是:Undefined,Null,Boole...

  • javascript深浅拷贝

    underscore 的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有...

  • JavaScript深浅拷贝

    简单讲呢,深浅拷贝,都是进行复制,那么区别主要在于复制出来的新对象和原来的对象是否会互相影响,改一个,另一个也会变...

  • Javascript深浅拷贝

    浅拷贝 1.基本数据类型 是存在栈中的,所以=赋值,都会创建一个新的空间,例如 变量b有自己独立的空间 2.对象数...

  • JavaScript深浅拷贝

    原文链接 http://blog.poetries.top/2018/12/21/js-deep-copy/ 关注...

  • Javascript深浅拷贝

    拷贝 复制与拷贝 复制:将一个对象a赋值给另一个变量b,这个只是存储了对象a的引用地址,是属于同一个对象 克隆:创...

  • JavaScript深浅拷贝

    一般来说,我们拷贝数据的时候:如果是基本数据类型,则会生成新的数据,修改拷贝后的数据不会影响原有数据。如果是对象/...

  • JavaScript 深浅拷贝

    深拷贝: 深拷贝即创建新的内存地址保存值(互不影响)浅拷贝: 共用同一内存地址,你改变我也跟着变 总结:slice...

网友评论

      本文标题:JavaScript - 深浅拷贝Object.assign()

      本文链接:https://www.haomeiwen.com/subject/iguynctx.html