资讯专栏INFORMATION COLUMN

Javascript-深浅拷贝

layman / 3484人阅读

摘要:深浅拷贝简介中对于和这两个类型,把一个变量赋值给另一个变量浅拷贝只是对拷贝对象的引用,深拷贝是彻底拷贝,生成一个新的属性相同的对象浅拷贝浅拷贝只是对拷贝对的引用,两者相互影响浅拷贝的实现简单赋值实现例子拷贝了,改变,也会改变,改变之后者还是

深浅拷贝简介

javascript中对于Object和Array这两个类型,把一个变量赋值给另一个变量;浅拷贝只是对拷贝对象的引用,深拷贝是彻底拷贝,生成一个新的属性相同的对象

浅拷贝(shallow copy)

浅拷贝只是对拷贝对的引用,两者相互影响

浅拷贝的实现 1.简单赋值实现

例子:obj2拷贝了obj1,obj2改变,obj1也会改变,改变之后2者还是相同的

    var obj1 = {a: 1}
    var obj2 = obj1
    obj2.b = 2
    console.log(obj1) // {a: 1, b: 2}
    console.log(obj2) //{a: 1, b: 2}
    console.log(obj1 == obj2) // true
Object.assign()实现

例子:当第一个传参是你需要拷贝的对象(PS:Object.assign()也可以实现深拷贝)

    var obj1 = {a: 1}
    var obj2 = Object.assign(obj1)
    obj2.b = 2
    console.log(obj1) // {a: 1, b: 2}
    console.log(obj2) // {a: 1, b: 2}
    console.log(obj1 == obj2) // true
深拷贝(deep copy)

彻底拷贝,生成一个新的属性相同的对象

深拷贝的实现 Object.assign()实现

例子:拷贝对象不是第一个传参

    var obj1 = {a: 1}
    var obj2 = Object.assign({}, obj1)
    obj2.b = 2
    console.log(obj1) // {a: 1}
    console.log(obj2) // {a: 1, b: 2}
    console.log(obj1 == obj2) // false
Array.slice()可以实现数组的深拷贝(数组中不能有Object和Array,Object和Array只是浅拷贝)
    var arr1 = [1, [2]]
    var arr2 = arr1.slice()
    arr2[1].push(3)
    arr2.push(4)
    console.log(arr1) // [1, [2, 3]]
    console.log(arr2) // [1, [2, 3], 4]
    console.log(arr1 == arr2) // false
JSON.stringify()和JSON.parse()实现
    var obj1 = {a: 1}
    var obj2 = JSON.parse(JSON.stringify(obj1))
    console.log(obj1 == obj2) // false
    obj2.b = 2
    console.log(obj1) // {a: 1}
    console.log(obj2) // {a: 1, b: 2}
递归实现
    var deepCopy = function(obj) {
        if (typeof obj !== "object") return;
        var newObj = obj instanceof Array ? [] : {};
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                newObj[key] = typeof obj[key] === "object" ? deepCopy(obj[key]) : obj[key];
            }
        }
        return newObj;
    }
    var obj1 = {a: 1}
    var obj2 = deepCopy(obj1)
    console.log(obj1 == obj2) // false
    obj2.b = 2
    console.log(obj1) // {a: 1}
    console.log(obj2) // {a: 1, b: 2}
Object.create()实现
    var deepCopy = function(obj) {
        if (typeof obj !== "object") return;
        var newObj = obj instanceof Array ? [] : {};
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                newObj[key] = typeof obj[key] === "object" ? Object.create(obj[key]) : obj[key];
            }
        }
        return newObj;
    }
    var obj1 = {a: 1}
    var obj2 = deepCopy(obj1)
    console.log(obj1 == obj2) // false
    obj2.b = 2
    console.log(obj1) // {a: 1}
    console.log(obj2) // {a: 1, b: 2}
jQuery.extend()实现
    var obj1 = {a: 1}
    var obj2 = $.extend(true, {}, obj1)
    console.log(obj1 == obj2) // false
    obj2.b = 2
    console.log(obj1) // {a: 1}
    console.log(obj2) // {a: 1, b: 2}

jQuery.extend()源码

    jQuery.extend = jQuery.fn.extend = function() {
        var src, copyIsArray, copy, name, options, clone,
            target = arguments[0] || {}, // 默认取第一个参数赋值给target
            i = 1,
            length = arguments.length, // 获取参数的个数
            deep = false; // 默认浅拷贝

        // Handle a deep copy situation
        if ( typeof target === "boolean" ) { // 如果第一个参数类型为boolean,那么把该参数赋值给局部变量deep
            deep = target;  
            target = arguments[1] || {}; // 把第二个参数赋值给target
            // skip the boolean and the target
            i = 2;
        }

        // Handle case when target is a string or something (possible in deep copy)
        if ( typeof target !== "object" && !jQuery.isFunction(target) ) { // target不是object类型或者不是function,就赋值{}
            target = {};
        }

        // extend jQuery itself if only one argument is passed
        if ( length === i ) { // 如果只有一个参数,这时候i就是1,length也就是1,那么把target设置为调用者,也就是jQuery对象本身!同时把i递减为0
            target = this; // this就是jQuery
            --i;
        }

        for ( ; i < length; i++ ) { // 循环参数
            // Only deal with non-null/undefined values
            if ( (options = arguments[ i ]) != null ) {
                // Extend the base object
                for ( name in options ) {
                    src = target[ name ]; 
                    copy = options[ name ];

                    // Prevent never-ending loop
                    if ( target === copy ) { // 防止无休止循环
                        continue;
                    }

                    // Recurse if we"re merging plain objects or arrays
                    // deep是否深拷贝,copy是参数属性值
                    if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                        if ( copyIsArray ) { // 被拷贝的属性值是数组
                            copyIsArray = false;
                            clone = src && jQuery.isArray(src) ? src : [];
                        } else { // 不是数组
                            clone = src && jQuery.isPlainObject(src) ? src : {};
                        }

                        // Never move original objects, clone them
                        target[ name ] = jQuery.extend( deep, clone, copy );  // 递归~

                    // Don"t bring in undefined values
                    } else if ( copy !== undefined ) {  // 浅拷贝,且属性值不为undefined
                        target[ name ] = copy;
                    }
                }
            }
        }

        // Return the modified object
        return target;
    };
更多方法...敬请期待

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98026.html

相关文章

  • Javascript对象的深浅拷贝

    摘要:开门见山,有人叫对象的复制为深复制浅复制,也有人叫深拷贝浅拷贝。高级属性修改深拷贝满足对象的复制,浅拷贝影响原数组。关于对象的深浅拷贝,暂且探索到这里,后续有新发现再进行补充。 showImg(https://segmentfault.com/img/remote/1460000014305581); 开门见山,有人叫对象的复制为深复制浅复制,也有人叫深拷贝浅拷贝。其实都是copy。 ...

    qieangel2013 评论0 收藏0
  • JavaScript专题之深浅拷贝

    摘要:专题系列第六篇,讲解深浅拷贝的技巧和以及实现深浅拷贝的思路前言拷贝也是面试经典呐数组的浅拷贝如果是数组,我们可以利用数组的一些方法比如返回一个新数组的特性来实现拷贝。所以我们可以看出使用和是一种浅拷贝。 JavaScript 专题系列第六篇,讲解深浅拷贝的技巧和以及实现深浅拷贝的思路 前言 拷贝也是面试经典呐! 数组的浅拷贝 如果是数组,我们可以利用数组的一些方法比如:slice、co...

    RancherLabs 评论0 收藏0
  • JavaScript深浅拷贝

    摘要:什么是深浅概念深拷贝浅拷贝只针对像这样的对象,对于基本类型而言,可以理解为是没有深浅的区别的。和指向了同一块内存深拷贝重新开辟了一个空间,修改对象的属性,彼此不会影响。并不会更改使用递归适用于对象里面有对象 什么是深浅 概念 深拷贝、浅拷贝只针对像Object/Array这样的对象,对于基本类型而言,可以理解为是没有深浅的区别的。 浅拷贝复制的是引用,修改对象的属性,会彼此影响。 ju...

    zhunjiee 评论0 收藏0
  • javascript深浅拷贝

    摘要:为何写最近在研究深浅拷贝,找了很多资料,感觉不是很满意,所以自己就整理了一份。深拷贝如果给放到新的内存中,将的各个属性都复制到新内存里,就是深拷贝。安全的值是指能够呈现为有效格式的值。参考文档冴羽的专题之深浅拷贝深拷贝与浅拷贝的实现 为何写: 最近在研究深浅拷贝,找了很多资料,感觉不是很满意,所以自己就整理了一份。废话不多说,我们来一起复习一下吧,也希望留下您宝贵意见。 何为深浅拷贝?...

    LMou 评论0 收藏0
  • 深浅拷贝

    摘要:深复制实现代码如下第一种方法通过递归解析解决第二种方法通过解析解决作者六师兄链接原生深拷贝的实现处理未输入新对象的情况通过方法构造新的对象 深浅拷贝针对的是 对象类型,如果是字符串的数组用[...arr],还是不会影响 要区分针对数组的深浅拷贝(默认情况为里面没有对象的数组),与针对对象的深浅拷贝 JavaScript数组深拷贝和浅拷贝的两种方法 let a1 = [1, 2]; ...

    Karrdy 评论0 收藏0
  • 复习Javascript专题(四):js中的深浅拷贝

    摘要:基本数据类型的复制很简单,就是赋值操作,所以深浅拷贝也是针对,这类引用类型数据。它会抛弃对象的。另外,查资料过程中还看到这么一个词结构化克隆算法还有这一篇资料也有参考,也写得比较详细了的深浅拷贝 基本数据类型的复制很简单,就是赋值操作,所以深浅拷贝也是针对Object,Array这类引用类型数据。 浅拷贝对于字符串来说,是值的复制,而对于对象来说则是对对象地址的复制;而深拷贝的话,它不...

    MobService 评论0 收藏0

发表评论

0条评论

layman

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<