最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JS 深拷贝与浅拷贝

    正文概述 掘金(Umbrella1024)   2021-02-18   522

    其实在工作写代码和面试中,会经常碰到这两个概念:深拷贝,浅拷贝。但今天的重点是深拷贝。

    下面我将简单介绍下什么是深拷贝,浅拷贝?

    浅拷贝就是直接将一个Object对象所有的属性和属性值复制给另一个Object对象。这样导致的后果是,新对象和老对象相同的Object类型的属性值在内存中的指向是一样的,也就是新对象和老对象的Object类型的同一属性值指向的是同一块内存。因此修改新对象或者原对象,都会互相干扰。

    深拷贝是将一个Object对象的内容完全拷贝一份给新对象。修改原对象的属性或者属性值,都不会影响新对象。原对象和新对象是完全独立的,互不影响。

    今天的重点是深拷贝,浅拷贝没啥可讲的。 talk is cheap,show me the code!

    上浅拷贝代码:

    function shallowCopy(obj) {
        if (!(obj instanceof object)) {
            return obj;
        }
        let newObj = {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                newObj[key] = obj[key];
            }
        }
        return newObj;
    }
    

    下面重点说说深拷贝

    第一个方案是使用JSON.stringify将Object转化为Json字符串,然后在用JSON.parse将json字符串转为Object对象。我们来测试下:

    let obj1 = { "name": "Umbrella", "sex": "man" };
    let obj2 = obj1;//浅拷贝
    obj2.name = "Umbrella1024";
    
    console.log(obj1);
    
    let obj3 = JSON.parse(JSON.stringify(obj1));
    console.log(obj3);
    obj1.sex = "boy";
    console.log(obj3);
    

    下面是运行截图

    JS 深拷贝与浅拷贝

    我们可以看到,浅拷贝后,源对象和新对象会互相影响,改了obj2,obj1就随之改变了。

    利用JSON.stringify、JSON.parse实现的深拷贝,是可以实现深拷贝的。 我们再给对象加多点属性,比如加个函数。

    let obj4 = {
        "name": "Umbrella",
        "sex": "man",
        "introduce": function () {
            console.log("My name is " + this.name);
        }
    };
    
    obj4.introduce();
    
    let obj5 = JSON.parse(JSON.stringify(obj4));
    console.log(obj5);
    obj5.introduce();
    

    JS 深拷贝与浅拷贝

    JS 深拷贝与浅拷贝

    可以看到采用这种方法,只可以将对象的非Function属性拷贝出来。所以通过JSON.parse和JSON.stringify实现的深拷贝不完美。

    那么我分享下我自己写的一个对象深拷贝的方法,这就是我个人比较常用的方案了。

    function deepCopy(obj) {
        if (obj instanceof Object) {
            let newObj = {};
            if (Array.isArray(obj)) {
                let arr = [];
                obj.forEach(item => {
                    arr.push(deepCopy(item));
                })
                return arr;
            } else {
                for (let key in obj) {
                    let value = obj[key];
                    if (typeof value == 'function') {
                        newObj[key] = value.bind(newObj);
                    } else if (typeof value == 'object') {
                        if (Array.isArray(value)) {
                            newObj[key] = [];
                            value.forEach(item => {
                                newObj[key].push(deepCopy(item));
                            })
                        } else {
                            newObj[key] = deepCopy(value);
                        }
                    } else {
                        newObj[key] = value;
                    }
                }
            }
            return newObj;
        } else {
            return obj;
        }
    }
    

    可以看到,我写的这个方法中,对属性值为function的做了处理。

    我们来对这个deepCopy做测试,看是否是满足需求,可用的。

    let obj88 = {
        "name": "obj88",
        "sex": "man",
        "introduce": function () {
            console.log("My name is " + this.name);
        }
    }
    
    let obj8 = {
        "name": "Umbrella",
        "sex": "man",
        "introduce": function () {
            console.log("My name is " + this.name);
        },
        "brothers": [obj88]
    };
    
    console.log(obj8);
    
    let obj9 = deepCopy(obj8);
    obj9.name = "Flex";
    
    console.log(obj8);
    console.log(obj9);
    
    obj88.name = "obj88 Plus";
    obj9.introduce();
    obj9.brothers[0].introduce();
    

    运行结果:

    JS 深拷贝与浅拷贝

    可以看到,我们的deepCopy函数是能够实现深拷贝的,并且也兼容了属性值类型为function的处理,也是可以拷贝的。

    如有错误或者不足的地方,欢迎大佬们来拍砖~


    起源地下载网 » JS 深拷贝与浅拷贝

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元