js 数组对象的深浅拷贝

本文详细解析了JS中数组深浅拷贝的原理与区别,并通过实例展示了如何实现对象的深层复制。

一 数组的深浅拷贝

最近在网上看到一篇关于js数组复制最有效的方法是直接使用slice和concat方法。这2个方法的确是最快的把数组成功复制,而不是引用。可以运行实例:

复制代码
<script type="text/javascript">
<!--
    var arr1=["1","2","3"],arr2;
    arr2=arr1.slice(0);
    arr1[0]=0; //改变arr1第一个元素
    alert("arr2[0]:"+arr2[0]);  //不影响arr2
    var arr3=["1","2","3"],arr4;
    arr4=arr3.concat();
    arr3[0]= 0;  //改变arr3第一个元素
    alert("arr4[0]:"+arr4[0]);  //不影响arr4
</script>
复制代码

运行结果可以看到改变原来数组中的元素并不影响拷贝后的数组。但是如果我们把上面例子中的a1换成[["1","2","3"],"2","3"],也就是二维数组,情况就不一样了。

复制代码
<script type="text/javascript">
<!--
    var a1=[["1","2","3"],"2","3"],a2;
    a2=a1.slice(0);
    a1[0][0]=0; //改变a1第一个元素中的第一个元素
    alert(a2[0][0]);  //影响到了a2
-->
</script>
复制代码

可以看到这2个方法只是复制了数组的第一维,由于数组第一维存放的是第二维的引用,而第二维才是实际存放他们的内容。就此我们可以联想到网上流行的复制对象的函数,其实也只是复制对象的第一层。

复制代码
<script type="text/javascript">
<!--
    function extend(destination,source)
    {
        for(var property in source)
        {destination[property]=source[property];}
    }
-->
</script>
复制代码

所以要想深层复制对象,还得在该函数基础上修改下。完整实例如下:

复制代码
<script type="text/javascript">
<!--
    function getType(o)
    {
        var _t;
        return ((_t = typeof(o)) == "object" ? o==null && "null" || Object.prototype.toString.call(o).slice(8,-1):_t).toLowerCase();
    }
    function extend(destination,source)
    {
        for(var p in source)
        {
            if(getType(source[p])=="array"||getType(source[p])=="object")
            {
                destination[p]=getType(source[p])=="array"?[]:{};
                arguments.callee(destination[p],source[p]);
            }
            else
            {
                destination[p]=source[p];
            }
        }
    }
    var test={a:"ss",b:"dd",c:{d:"css",e:"cdd"}};
    var test1={};
    extend(test1,test);
    test1.c.d="change"; //改变test1的c属性对象的d属性
    alert(test.c.d);  //不影响test
-->
</script>

二、对象的深浅拷贝

复制代码
var a={name:'yy',age:26};
var b=new Object();


b.name=a.name;
b.age=a.age;
a.name='xx';
console.log(b);//Object { name="yy", age=26}
console.log(a);//Object { name="xx", age=26}
复制代码

就是把对象的属性遍历一遍,赋给一个新的对象。

复制代码
var deepCopy= function(source) { 
var result={};
for (var key in source) {
      result[key] = typeof source[key]===’object’? deepCoyp(source[key]): source[key];
   } 
   return result; 
}
好的,关于JavaScript中数组深浅拷贝的问题,我可以为你做一个简要的介绍并举个例子。 首先来看浅拷贝,它会创建一个新的数组,这个新数组中的元素是对原始数组中对应元素的引用。这意味着如果修改原始数组中的元素,新数组中对应的元素也会受到影响。下面是一个浅拷贝的例子: ```javascript var originalArray = [1, 2, 3, 4]; var newArray = originalArray.slice(); originalArray[2] = 'changed'; console.log(originalArray); // [1, 2, "changed", 4] console.log(newArray); // [1, 2, 3, 4] ``` 上面代码中使用了 `slice()` 方法进行了拷贝操作。我们修改了原始数组中的第三个元素,发现新的数组并没有发生变化。 接下来再看深拷贝,它会创建一个新的数组,并且完全复制原始数组中的所有元素,这意味着即使修改原始数组中的元素,新数组中对应的元素也不会受到影响。由于JavaScript中没有原生的深拷贝方法,我们通常需要使用递归函数或第三方库来实现。下面是一个使用 JSON 序列化和反序列化实现深拷贝的例子: ```javascript var originalArray = [1, 2, [3, 4]]; var newArray = JSON.parse(JSON.stringify(originalArray)); originalArray[2][0] = 'changed'; console.log(originalArray); // [1, 2, ["changed", 4]] console.log(newArray); // [1, 2, [3, 4]] ``` 注意,使用 `JSON.stringify()` 和 `JSON.parse()` 实现深拷贝的时候,要确保原始数组仅包含可以被 JSON 序列化的数据类型,例如数字、字符串、布尔值、null 以及包含这些类型的数组对象。如果原始数组中包含了函数、undefined、Symbol 等类型,这种方法就会出现问题了。 希望这个简单的例子能够帮助你理解 JavaScript 中数组深浅拷贝的概念。如果你还有其他问题,请随时向我提出。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值