今天和一个朋友讨论到JavaScript中一些引用数据类型的复制问题,由于引用数据类型是传址复制,如果想达到真正的“复制”效果(即修改一个 变量的值不会影响另一个的值),就不能使用像 var b = a; 这样的语句,对于引用类型来说,这样复制的结果就是当a的值发生变化时,b也会发生同样的变化,因为这时a真正的值只是对一个地址的引用,b复制到的也只 是这个相同地址的引用而已,于是当a和b其中一个被修改之后,另一个也随之改变,有些时候这并不是我们想要的。

这样的问题遇到最多的就是在处理数组和json对象时。对于数组,我们有很方便的内置方法可以使用:

var arrayA = [1,2];
    var arrayB = arrayA.concat();
    arrayA[0] = [2];

    //数组arrayA 被修改之后,arrayB依然维持之前拷贝的值
    console.log(arrayA);
    console.log(arrayB);

上面的代码中,核心只有一个方法: concat,对于数组而言,这个方法在传入数组类型的参数时用于合并两个或多个数组,在不传参数时,将原数组拷贝到一个新的地址,并返回这个新地址的引用。

json的情况稍微麻烦一点,在原生JavaScript中似乎并没有直接提供这样的方法,好在手工达到这一目的并不需要花费什么精力:

var objA = {"val" : {"name" : "myName"}};
    var objB = {};    //创建一个新的json对象,用于接收objA的值

    for(var i in objA){
    //遍历objA,将其中的每一组“键值”原样拷贝到objB中
    //不用担心多维的情况,它不会带来任何问题
        objB[i] = objA[i];
    }

    var objA["val"] = {"name" : "yourName"};
    console.dir(objA);
    console.dir(objB);
    //这是objB已经完全拷贝了objA
    //而objA再改变也不会对objB产生影响

如果你有更好的办法,非常欢迎指出来和大家一起分享。