js深浅拷贝

一.原因和区别:
javascript的基本类型有:字符串,数字,布尔,null,undefined,对象(数组,正则表达式,日期,函数) ,大致分为俩种:基本数据类型和引用数据类型

基本数据类型:数字,字符串,null,undefined
引用类型:对象

基本数据类型保存在栈内存中(保存在栈内存中的必须是大小固定的数据),如果是基本数据类型,则按值访问的,就是在操作基本类型时,直接修改变量的值.
引用类型保存在堆内存中(大小不固定,只能保存在堆内存中),如果是引用类型的的值,我们只是通过保存在变量中的引用类型的地址来操作实际对象

浅拷贝:
浅拷贝只是拷贝基本类型的数据,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,因此存在父对象被篡改的可能,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存
深拷贝:
深拷贝会另外创造一个一模一样的对象,新对象跟原对象占用不同的内存空间,修改新对象不会改到原对象

二.实现深拷贝的方法

  1. slice
var arr1 = ['a', 'b'], arr2 = arr1.slice();
console.log(arr1); // ["a", "b"]
console.log(arr2); // ["a", "b"]
arr2[0] = 'c'; //修改arr2
console.log(arr1); // ["a", "b"]
console.log(arr2); // ["c", "b"]

此时,arr2的修改并没有影响到arr1,看来深拷贝的实现并没有那么难嘛。
2) concat

var arr1 = ['a', 'b'], arr2 = arr1. concat ();
console.log(arr1); // ["a", "b"]
console.log(arr2); // ["a", "b"]
arr2[0] = 'c'; //修改arr2
console.log(arr1); // ["a", "b"]
console.log(arr2); // ["c", "b"]
我们把arr1改成二维数组再来看看:
var arr1 = ['a', 'b', ['c', 'd']], arr2 = arr1.concat();
arr2[2][1] = 100;
console.log(arr1); //['a', 'b', ['c', 100]]
console.log(arr2); //['a', 'b', ['c', 100]]

咦,arr2又改变了arr1,看来slice()/concat()只能实现一维数组的深拷贝
3) 调用json内置方法先序列化为字符串,再解析还原成对象

newObj=JSON.parse(JSON.stringify(obj));

缺陷:JSON是一种表示结构化数据的格式,只支持简单值、对象和数组三种类型,不支持变量、函数或对象实例。所以我们工作中可以使用它解决常见问题,但也要注意其短板:函数会丢失,原型链会丢失,以及上面说到的所有缺陷。
4) 递归函数

//深拷贝的实现
  var deepClone = function(currobj){
    if(typeof currobj !== 'object'){
        return currobj;
    }
    if(currobj instanceof Array){
        var newobj = [];
    }else{
        var newobj = {}
    }
    for(var key in currobj){
        if(typeof currobj[key] !== 'object'){
            // 不是引用类型,则复制值
            newobj[key] = currobj[key];
        }else{
            // 引用类型,则递归遍历复制对象
            newobj[key] = deepClone(currobj[key])    
        }
    }
    return newobj
}

总结:
1.赋值运算符 = 实现的是浅拷贝,只拷贝对象的引用值;
2.JavaScript 中数组和对象自带的拷贝方法都是“首层拷贝”;
3.JSON.stringify 实现的是深拷贝,但是对目标对象有要求;
4.若想真正意义上的深拷贝,请递归。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值