JS深拷贝的方法

先看一个例子

    var a = [1,2,3,4,5,6];
    var b = a;
    b.push('b');
    console.log(a);
    console.log(b);

输出结果:

 [1, 2, 3, 4, 5, 6, "b"]
 [1, 2, 3, 4, 5, 6, "b"]

是不是和想象中的完全不一样,我们改变的只是b数组,结果a数组也发生了变化;这就牵涉到今天的主题-------深拷贝

深拷贝(deepClone):对于一个引用类型,如果直接将他赋值给另一个变量,由于这两个引用指向同一个地址,这时改变其中的任何一个引用,另一个引用都会收到影响,当我们想复制一个对象并且切断这个对象的联系,就要使用深拷贝;

方案一:利用递归来解决:

//对元素的类型进行判断
    function getType(obj) {
        var toString = Object.prototype.toString();
        var map = {
            '[object Boolean]'  : 'boolean',
            '[object Number]'   : 'number',
            '[object String]'   : 'string',
            '[object Function]' : 'function',
            '[object Array]'    : 'array',
            '[object Date]'     : 'date',
            '[object RegExp]'   : 'regExp',
            '[object Undefined]': 'undefined',
            '[object Null]'     : 'null',
            '[object Object]'   : 'object'
        };
        if( obj instanceof Element){
            return 'element';
        };
        return map[toString.call(obj)];
    }

//深度拷贝
    function deepClone(data) {
        var type = getType(data);
        var obj;
        if( type === 'array' ){
            obj = [];
        }else if( type === 'object' ){
            obj = {};
        }else {
            return data;
        }

        if( type === 'array' ){
            for( var i = 0;i < data.length;i++ ){
                obj.push(deepClone(data[i]));
            }
        }else if( type === 'object' ){
            for( var key in data ){
                obj[key] = deepClone(data[key]);
            }
        }

        return obj;
    }

方案二:利用数组contact方法

        var a = [1, 2];
        var b = a.concat();
        b.push(5);
        console.log(a);
        console.log(b);

contact方法连接数组返回的是一个新数组;

对象的拷贝:

        var c = {c1: 1, c2: 2};
        var d = Object.assign(new Object(), c);
        d.d3 = 3;
        console.log(c);
        console.log(d);

 方案三:利用数组的map方法

map()方法能够对数组进行遍历,并且回调函数中支持return返回值,不会影响原本的数组,只是吧原来的数组克隆了一份;

var ary = [12,23,24,42,1];  
var res = ary.map(function (item,index,input) {  
    return item;  
})  
res.push(100);
console.log(res);//-->[12,23,24,42,1,100];  原数组拷贝了一份,并进行了增加了长度
console.log(ary);//-->[12,23,24,42,1];  原数组并未发生变化
扫描二维码关注公众号,回复: 3382534 查看本文章

猜你喜欢

转载自blog.csdn.net/u013935095/article/details/81134826