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;
        }
    }
  • 相关阅读:
    centos 编码问题 编码转换 cd到对应目录 执行 中文解压
    centos 编码问题 编码转换 cd到对应目录 执行 中文解压
    centos 编码问题 编码转换 cd到对应目录 执行 中文解压
    Android MVP 十分钟入门!
    Android MVP 十分钟入门!
    Android MVP 十分钟入门!
    Android MVP 十分钟入门!
    mysql备份及恢复
    mysql备份及恢复
    mysql备份及恢复
  • 原文地址:https://www.cnblogs.com/coderL/p/7728058.html
Copyright © 2011-2022 走看看