深入理解js深浅拷贝

一、基本概念

要深入理解深浅拷贝,那么需对计算机语言的堆和栈有一定的理解。

栈:javascript的基本类型就5种:Undefined 、Null、Boolean、Number和String,它们都是直接按值存储在栈中,每种类型的数据占用的内存空间的大小是确定的,栈由系统自动分配。

堆:javascript中其他类型的数据被称为引用类型的数据;如对象(Object)、数组(Array)、函数(Function)…

引用类型的数据的地址指针是存储于栈中的,当我们想要访问引用类型的值时,需要先从栈中获得对象的地址指针,然后,在通过地址指针找到堆中所需要的数据。

目前JavaScript有五种基本数据类型(也就是简单数据类型),它们分别是:Undefined,Null,Boolean,Number和String。还含有一种复杂的数据类型(也叫引用类型),就是对象,引用类型有:Object、Array、Function

深浅拷贝是发生在引用数据类型上

二、深浅拷贝情况分析

eg:

var  a = {x: 1, y: 1} , b = a;
console.log(a)  //{x: 1, y: 1};
console.log(b)  //{x: 1, y: 1};
a.x = 2;  //修改b.x
console.log(a);   // {x: 2,y: 1}
console.log(b);   // {x: 2,y: 1}

这里b随着a的改变而改变了,那说明了什么呢?

简单来说,假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,如果B没变,那就是深拷贝;

三、深拷贝的方法

  1. JSON.parse(JSON,stringify(obj))
var obj = {
        name: 'star',
        age: 19,
        friend:{
            id:'1',
            name: 'xiaohong'
        }
    }
    var obj2 = JSON.parse(JSON.stringify(obj));
    obj.friend.id = "2";
    
   console.log(obj);  // { name: 'star', age: 19, friend: { id: '2', name: 'xiaohong' } }
   console.log(obj2);  // { name: 'star', age: 19, friend: { id: '1', name: 'xiaohong' } }
  1. Object 利用对象的深拷贝实现原理
    定义一个新的对象,遍历源对象的属性并赋给新对象的属性
var obj3 = {
        name: 'star',
        age: 19,
        friend:{
            id:'1',
            name: 'xiaohong'
        }
    }
    
    var obj4 = new Object();

    obj4.name  = obj3.name;
    obj4.age  = obj3.age;
    obj3.name = 'ronnie'
    console.log(obj3);  // { name: 'ronnie', age: 19, friend: { id: '1', name: 'xiaohong' } }
    console.log(obj4); // { name: 'star', age: 19 }

根据上面的基本思想,封装一个方法deep来实现对象的深浅拷贝

    var obj = {
        name: "star",
        skin: ["red", "green"],
        child: {
            name: "xxxx"
        },
        say: function(){
            console.log("我是", this.name, "skin", this.skin, "child", this.child)
        }
    }
    var copyObj = new Object();
    function deep(copyObj,obj){
        var o = copyObj;
        for(var key in obj){
            if(typeof obj[key] === 'object'){
                o[key] = (obj[key].constructor === Array)?[]:{}
                deep(o[key],obj[key])
            }else{
                o[key] = obj[key]
            }
        }
        return o;
    }
    copyObj.name = "honghong";
    copyObj.skin = ["blue"];
    console.log(obj, '我是obj') 
    // {
  name: 'star',
  skin: [ 'red', 'green' ],
  child: { name: 'xxxx' },
  say: [Function: say]
} 我是obj

    console.log(copyObj, '我是copyObj')
    // { name: 'honghong', skin: [ 'blue' ] } 我是copyObj

以上代码都是可以直接用代码工具运行哟,亲测有效哦!
欢迎在留言板进行交流!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值