您的位置:首页 > Web前端 > JavaScript

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

2009-11-18 14:09 537 查看
问题:

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

这里我将提出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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: