zoukankan      html  css  js  c++  java
  • javascript浅拷贝深拷贝详解

    一、浅拷贝

    浅拷贝在现实中最常见的表现在赋值上面,例如

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>测试</title>
    </head>
    <body>
        <script type="text/javascript">
            //第一个数组
            var test=["1","2","3"];
            //第二个数组
            var test2=[];
            test2=test;
            test2[1]="two";
            console.log(test);//运行的结果是["1","two","3"]
        </script>
    </body>
    </html>
    复制代码

    从上面的例子,我们修改test2数组的值,最后打印test数组,发现test也跟着改变了。

    其实这个就是一个最浅的浅拷贝,相当于test2=test这个阶段是在将test数组中的存储地址索引赋值给test2数组,所以两个数组都是指向同一块存储地址中去。

    除了这种方法可以实现浅拷贝,还有使用sliceconcat进行浅拷贝

    例如:我们测试一次slice这个方法(可从已有的数组中返回选定的元素为新数组

    复制代码
    <script type="text/javascript">
        var arr=["demo1","demo2","demo3"];
        var arr2=arr.slice(0);
        arr2[1]="test";
        console.log(arr);//["demo1","demo2","demo3"]
        console.log(arr2);//["demo1","test","demo3"]
    </script>
    复制代码

    从上面的例子我们可以看出,使用slice方法对数组进行了深度拷贝,

    同理,concat的用法如下(用于连接两个或多个数组为新数组)

    复制代码
    <script type="text/javascript">
        var arr=["demo1","demo2","demo3"];
        var arr2=arr.concat();
        arr2[1]="test";
        console.log(arr);//["demo1","demo2","demo3"]
        console.log(arr2);//["demo1","test","demo3"]
    </script>
    复制代码

    为何这样已经算得上是深拷贝的东西,我又称之为浅拷贝呢?

    对于Slice和concat这两个方法来说都是浅拷贝,只能深拷贝数组中的第一层

    当数组内为对象时,则是浅拷贝

    二、深拷贝

    1.通过内置的js函数

    复制代码
    function deepCopy(o){
        return JSON.parse(JSON.stringify(o));
    }
    var a = {a:1,b:2,c:3};
    var b = deepCopy(a);
    b.a = 4;
    alert(a.a); //1        
    alert(b.a); //4,将b.a赋值为4,不会影响到a对象,a.a仍是1
    复制代码

    这种方式很好理解,对一个Object对象而言,

    先使用内置的JSON.stringify()函数,将其转化为字符串       "{"a":1,"b":2}"

    此时生成的字符串已经和原对象没有任何联系了,再通过JSON.parse()函数,将生成的字符串转化为一个新的对象。 {a: 1, b: 2}

    而在新对象上的操作与旧对象是完全独立的,不会相互影响。这种方法的优点就是简单易懂,使用js内置函数来实现,不需要太大的开销。

    2.以通过自己的方法实现,就是遍历数组或对象,返回新数组或者对象。

    var simpleCopy = function(o){
        if (o instanceof Array) {
            var n = [];
            for (var i = 0; i < o.length; ++i) {
                n[i] = o[i];
            }
            return n;
        } else if (o instanceof Object) {
            var n = {}
            for (var i in o) {
                n[i] = o[i];
            }
            return n;
        }
    }

    3.如何实现拷贝包含对象或者数组的这种情况呢?那么就通过递归拷贝来实现。

    var deepCopy = function(o) {
        if (o instanceof Array) {
            var n = [];
            for (var i = 0; i < o.length; ++i) {
                n[i] = deepCopy(o[i]);
            }
            return n;
    
        } else if (o instanceof Object) {
            var n = {}
            for (var i in o) {
                n[i] = deepCopy(o[i]);
            }
            return n;
        } else {
            return o;
        }
    }
  • 相关阅读:
    移动设备(手机)的唯一ID有哪些
    公司跟你聊企业文化了吗
    C#并行编程-线程同步原语
    C#并行编程-并发集合
    C#并行编程-Task
    C#并行编程-Parallel
    C#并行编程-相关概念
    C#学习系列-this的使用
    C#学习系列-out与ref的区别
    C#学习系列-抽象方法与虚拟方法的区别
  • 原文地址:https://www.cnblogs.com/coderL/p/7728058.html
Copyright © 2011-2022 走看看