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)

猜你喜欢

转载自blog.csdn.net/qq_41560520/article/details/115180968