JS深浅拷贝

Posted Kyara

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS深浅拷贝相关的知识,希望对你有一定的参考价值。

1.浅拷贝:

    将原对象或原数组的引用直接赋给新对象新数组新对象数组只是原对象的一个引用;

2.深拷贝:

    创建一个新的对象和数组将原对象的各项属性的”(数组的所有元素拷贝过来而不是引用”;

 

    使用深拷贝的场景

      在改变新的数组对象的时候不改变原数组对象);
 
 

深拷贝数组(只拷贝第一级数组元素)

    1.for循环遍历数组;
        var array = [1, 2, 3, 4, 5];
            function copy(array) {
                var newArray = []
                for (var i = 0; i < array.length; i++) {
                     newArray.push(array[i]);
                }
                return newArray;
            }
            var copyArray = copy(array);
            copyArray[0] = 100;
            console.log(array); // [ 1, 2, 3, 4, 5 ]
            console.log(copyArray); // [ 100, 2, 3, 4, 5 ]
        
    2.for in遍历数组;
        var array = [1, 2, 3, 4, 5];
            function copy(array) {
                var newArray = []
                for (var i in array) {
                    newArray.push(array[i]);
                }
                return newArray;
            }
            var copyArray = copy(array);
            copyArray[0] = 100;
            console.log(array); // [ 1, 2, 3, 4, 5 ]
            console.log(copyArray); // [ 100, 2, 3, 4, 5 ]
        
    3.silce();   //当slice()不带任何参数的时候,默认返回一个长度和原数组相同的新数组
        注意:利用slice();方法不改变原数组的特性
        var array = [1, 2, 3, 4, 5];
        var copyArray = array.slice();
            copyArray[0] = 100;
            console.log(array); // [1, 2, 3, 4]
            console.log(copyArray); // [100, 2, 3, 4]
        
    4.concat();  //用于连接两个或多个数组。( 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。)
        var array = [1, 2, 3, 4, 5];
        var copyArray = array.concat();
        copyArray[0] = 100;
        console.log(array); // [1, 2, 3, 4]
        console.log(copyArray); // [100, 2, 3, 4];

深拷贝对象(只拷贝第一级对象元素)

 

    1.直接遍历;
        var obj = {
            name: "admin",
            age: 18,
            sex: 0
        }
        var obj2 = {};
        for (var i in obj) {
            obj2[i] = obj[i];
        }
        obj2.name = "root";
        console.log(obj);  //{ name: "admin", age: 18, sex: 0 }
        console.log(obj2);  //{ name: "root", age: 18, sex: 0 }
    
    2.Object.assign:用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target),并返回合并后的target
        //ES6提供;
        用法: Object.assign(target, source1, source2);
            var obj = {
                name: ‘这是初始name‘,
                job: ‘这是初始job‘,
                age: 18
            }
            var copyObj = Object.assign({}, obj);
            copyObj.name = ‘这是拷贝后的name‘;
            console.log(obj); // { name: "这是初始name", job: "这是初始job", age: 18 }
            console.log(copyObj); // { name: "这是拷贝后的name", job: "这是初始job", age: 18 }

 

拷贝所有层级(忽略function,undefined等)

 

 var array = {
        name: "obj-1",
        profn: function(n) {
            return n * 2;
        },
        proArr: [1, 2, 3, 4],
        proObj: {
            a: "aa",
            b: "bb"
        },
        profn2: function(m, n) {
            return m + n;
        },
        proObj2: {
            pro1: "1212",
            pro2: {
                qq: "qq",
                ww: "ww"
            }
        }
    };
    var copyArray = JSON.parse(JSON.stringify(array))
    copyArray.name = "101";
    console.log(array); //{ name: "obj-1", profn: profn(), proArr: (4) [], proObj: {}, profn2: profn2(), proObj2: {} }
    console.log(copyArray); // { name: "101", proArr: (4) [], proObj: {}, proObj2: {} }

 

复杂

 

var obj1 = {
            name: "obj-1",
            profn: function(n) {
                return n * 2;
            },
            proArr: [1, 2, 3, 4],
            proObj: {
                a: "aa",
                b: "bb"
            },
            profn2: function(m, n) {
                return m + n;
            },
            proObj2: {
                pro1: "1212",
                pro2: {
                    qq: "qq",
                    ww: "ww"
                }
            }
        }
        console.log(obj1);    //{ name: "obj-1", profn: profn(), proArr: (4) […], proObj: {…}, profn2: profn2(), proObj2: {…} }
        function copyFn(obj) {
            if (obj == null) {
                return null
            }
            var result = Array.isArray(obj) ? [] : {};
            for (var key in obj) {
                if (obj.hasOwnProperty(key)) {
                    if (typeof obj[key] === ‘object‘) {
                        result[key] = copyFn(obj[key]); // 如果是对象,再次调用该方法自身
                    } else {
                        result[key] = obj[key];
                    }
                }
            }
            return result;
        }
        var obj2 = copyFn(obj1);
        obj2.name = ‘Edited‘;
        console.log(obj1);    //{ name: "obj-1", profn: profn(), proArr: (4) […], proObj: {…}, profn2: profn2(), proObj2: {…} }
        console.log(obj2);   //{ name: "Edited", profn: profn(), proArr: (4) […], proObj: {…}, profn2: profn2(), proObj2: {…} }

 

 

 

 

 

 

 

 

 

以上是关于JS深浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章

学姐面试宝典前端基础篇Ⅴ——JS深浅拷贝箭头函数事件监听等

简述深浅拷贝

js深浅拷贝

js的深浅拷贝

最简js深浅拷贝说明

JS深浅拷贝