js中关于数组复制的一些认识(感谢IT民工和见Q,如见人的指导)

 

问题:

很多时候,我们会有这样一个需求,我们定义了一个数组。但是我们需要拷贝一份数组备份出来做其他操作。原数组保留不变。

这里我将提出3个方法,并对某一个方法进行说明。这里会遇到一个很有意思的问题。就是值引用和地址引用的问题,并进行说明。

想法:

这里有三种想法:

1、遍历数组,将每一个数组元素(n层也是如此)。赋值到另一个新建数组。

2、自定义Array.prototype.Clone(){}方法,自己写方法体内容。

3、讨巧的使用默认方法concat()来实现。

分析:

1、方法1,显然不是可取的建议。又或者说对于追求编程艺术的我来说,这不是最推荐的。当然这并不代表他不能解决问题。

2、方法2,这是一个比较有趣的写法。代码如下:
function Array.prototype.clone(){
   var tmp=new Array();
   for(ob in this)tmp[ob]=this[ob];
   return tmp;
}
它确实会将数组元素拷贝一份给另一个数组。但是这里是会有问题的,或者说它会有一个有趣的地方。等下衍生分析里有说到。

3、方法3,这是一个很有意思的方法,对于这个方法的两个说明是“这项方法会合并两个或更多的数组。”、“这项方法会合并多个字符串成一个新的字符串,并将新的字符串当作返回值。”。这个方法的一个典型的应用是:
arr1 = [1, 2, 3];
arr2 = [];
arr2 = arr2.concat(arr1);
它也的确能拷贝一份数组给另一个数组。当时它依然会发生一些有趣的现象。等下衍生分析里会有说到。

它完成了吗?对于数组拷贝的进一步分析。

这里我们提出一个假设,即:1、当数组是一个二维的数组,2、当数组元素不是值类型。那么当数组拷贝的时候,它拷贝了什么?

这里我们主要尝试使用方法3来验证下。我们构建一个二维数组。
arr1 = [["abc1","abc2","abc3"],["abc1","abc2","abc3"],["abc1","abc2","abc3"]];
arr2 = [];
arr2 = arr2.concat(arr1);
arr1[0][0] = "not abc1";
alert(arr1);
alert(arr2);
arr1.shift();
alert(arr1);
alert(arr2);
说明:这两个都是二维数组,数组元素都不是值类型。当我执行arr1[0][0] = "not abc1";以后,arr2[0][0]的值也改变了。这个可以通过前两个alert()发现。而当我arr1.shift()之后,alert()的内容却发生了变化。

为什么呢?

有一个认识是这样的,1、arr1和arr2的第一维存放的其实是第二维的引用。而第二维则实际存放他们的内容。这样当使用arr1修改某一个具体 的第二维元素时,arr2实际将会使用的值也是那个经过修改的过的第二维数组。2、这两个数组的第一维引用确实不是同一个。图过用堆栈图来模拟的话,差不 多应该是如下这张图:

 

 

这样的话,应该就可以清晰的理解了1、为什么修改arr1[0][0]的值,arr2会变化。2、为什么arr1.shift()之后,alert()的值不一样。

最后一些反省

这个如果换作其他语言,应该是不会搞错的。到底没有很基础的学过js原理,这些问题,其实java,.net语系的基本概念都有说明过。

要好好学啊~~。

 

 

http://hi.baidu.com/gantianamin2001/blog/item/ff9a3af4b14e57dff3d3855d.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值