js深浅拷贝的理解

js深浅拷贝的理解

说起js的深浅拷贝不得不提起的是js的数据类型

  • 基本数据类型 :undfined string boolean null number
  • 引用数据类型:array object function
    基本数据类型存储在栈内存中
变量
a1(栈内存)
b(指针)

var a=1;var b = a a=3;console.log(a,b)//3,1
如上代码所示:
1.深拷贝与浅拷贝的区别
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,被人牵着鼻子走,如果B没变,那就是深拷贝,自立更生。
引用数据类型存储在堆内存中

var b={name:"张三",age:"25"}
var newobj = b;
b.name="李四"
"李四"
console.log(b,newobj)
 //{name: "李四", age: "25"} {name: "李四", age: "25"}

为什么会出现上述的结果呢?
因为newobj=b时只是复制了b在栈内存中的指针,而指针执行的只是堆内存中的一个地址,通过赋值给newobj 等于b和newobj都共用这块内存。

堆内存
(b) {name:“zhangsan”,age:“25”}

数组深拷贝:尝试过 slice concat 但只是拷贝了一层,并没有实现真正的拷贝
对象深拷贝:尝试过 Object.assign
使用Object.assign方式只拷贝了对象的第一层, 第二层或之后都只拷贝了指针;修改obj2第二层,obj1还是会跟着改变
那么怎么实现深拷贝呢?

深拷贝
 1.递归
function deepClone(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断ojb子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    //如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
} 

let a=[1,2,3,4],b=deepClone(a);
a[0]=2;
console.log(a,b);

2.JSON 对象的 parse 和 stringify都是深拷贝
这种方法能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,即那些能够被 json 直接表示的数据结构。RegExp对象是无法通过这种方式深拷贝。

var obj = {name:'zhangsan',age:23,company : { name : '阿里', address : '杭州'} };
var newobj = JSON.parse(JSON.stringify(obj));
obj.company.name = "阿里巴巴";
obj.name = "zhangsan1";
console.log(obj);//{name:'zhangsan1',age:23,company : { name : '阿里巴巴', address : '杭州'} }
console.log(newobj);// {name:'zhangsan',age:23,company : { name : '阿里', address : '杭州'} }

在这里插入图片描述
3.lodash函数库实现深拷贝
lodash很热门的函数库,提供了 lodash.cloneDeep()实现深拷贝
4.通过jQuery的extend方法实现深拷贝
var array = [1,2,3,4];
var newArray = $.extend(true,[],array);
5.使用Object.create()方法
直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。

function deepClone(initalObj, finalObj) {
    var obj = finalObj || {};
    for (var i in initalObj) {
        var prop = initalObj[i];
        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
        if(prop === obj) {
            continue;
        }
 
        if (typeof prop === 'object') {
            obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
        } else {
            obj[i] = prop;
        }
    }
    return obj;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值