js浅拷贝与深拷贝的区别和实现

浅拷贝,深拷贝,区别(敲黑板):

1.浅拷贝就类似于简单的赋值,比如let a=1;b=a,这就实现了简单的浅拷贝,修改a的值,b也会跟着改变,复制的是a的引用地址,而并非栈里面的值。

2.深拷贝就是b单独开辟出来了一块内存空间,无论a怎么变,跟b都没有任何关系,b不会因a变而变。

3.基本数据类型,名字和值都会储存在栈内存中。引用数据类型,名字存在栈内存中,值存在堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值

浅拷贝实现:

1.直接用=赋值

2.Object.assign()拷贝:当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。

var obj = {
    a: 1,
    b: 2
}
var obj1 = Object.assign(obj);
obj.a = 3;
console.log(obj1.a) // 3

3.for···in只循环第一层

function simpleCopy(obj1) {
    var obj2 = Array.isArray(obj1) ? [] : {};
    for (let i in obj1) {
    obj2[i] = obj1[i];
   }
    return obj2;
 }
 var obj1 = {
    a: 1,
    b: 2,
    c: {
          d: 3
       }
 }
 var obj2 = simpleCopy(obj1);
 obj1.a = 3;
 obj1.c.d = 4;
 console.log(obj1.a); // 3
 console.log(obj2.a); // 1
 console.log(obj1.c.d); // 4
 console.log(obj2.c.d); // 4

深拷贝实现:

1.递归遍历,拷贝所有层级属性

Es5写法:

 let obj = {
            name: '小明',
            age: 21,
            info: {
                hobby: ['唱歌', '跳舞', {
                    a: 1
                }],
                career: {
                    teacher: 4,
                    engineer: 9
                }
            }
        }
        //Es5深拷贝
        function deepClone(origin, target) {
            let tar = target || {}
            let toStr = Object.prototype.toString
            for (let k in origin) {
                if (origin.hasOwnProperty(k)) { //判断是不是自己的原型
                    if (typeof origin[k] === 'object' && origin[k] !== null) { //判断是不是object
                        tar[k] = toStr.call(origin[k]) === '[object Array]' ? [] : {}; //判断是不是数组类型
                        deepClone(origin[k], tar[k])
                    } else {
                    	//普通数据类型直接赋值
                        tar[k] = origin[k]
                    }
                }
            }
            return tar;
        }
        let deepobj = deepClone(obj)
        console.log('deepobj', deepobj)
        obj.name = '小红'
        console.log(obj)
        console.log('deepobj', deepobj)

在这里插入图片描述
Es6写法:

//Es6深拷贝
        function deepCloneEs6(origin, hashMap = new WeakMap()) {
            if (origin == undefined || typeof origin !== 'object') {
                return origin
            }
            if (origin instanceof Date) {
                return new Date(origin)
            }
            if (origin instanceof RegExp) {
                return new RegExp(origin)
            }
            const hashKey = hashMap.get(origin)
            if (hashKey) {
                return hashKey
            }

            const target = new origin.constructor(); //origin它的原型构造器,
            hashMap.set(origin, target)
            for (let k in origin) {
                if (origin.hasOwnProperty(k)) { //判断是不是自己的原型
                    target[k] = deepCloneEs6([origin[k]], hashMap)
                }
            }
        }
        let deepobjEs6 = deepClone(obj)
        console.log('deepobjEs6', deepobjEs6)
        obj.info.hobby[2].a = 123
        console.log(obj)
        console.log('deepobjEs6', deepobjEs6)

在这里插入图片描述

2.通过JSON对象来实现深拷贝,注意:无法实现对对象中方法的深拷贝,会显示为undefined

function deepClone2(obj) {
  var _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
  return objClone;
}

3.jQuery的extend方法实现深拷贝

var array = [1,2,3,4];
var newArray = $.extend(true,[],array); // true为深拷贝,false为浅拷贝

4.lodash函数库实现深拷贝:很热门的函数库,提供了 lodash.cloneDeep()实现深拷贝

let newResult = _.cloneDeep(test)
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

web前端小龚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值