Array可以看作是一种特殊的Object。
var v = [1,2,3,4,5]; function f_t(a){ a[1] = 9; } f_t(v); alert(v[1]); // 显示 9 , 值已经发生改变 v[1] = 2; f_t(v.slice()); alert(v[1]); // 显示 2 , 值没有发生改变
上面的例子说明JavaScript中的数组(Array)是按照地址来传递的。
如果要按照值传递,就要先对数组进行复制,这可以通过不带参数的slice()方法做到。
如上所述,JavaScript看人数组(Array)是按照地址赋值的。因此,如果要修改一个数组,却又不想改变原有数组的值的情况下,就需要对数组进行复制。
复制数组的办法,最容易想到的自然是新建一个数组然后逐项复制。较便捷的方法是利用Array.slice
函数。
需要注意的是slice
方法只能用于Shallow Copy,如果要进行Depp Copy,还是需要更多编码才行。参见:JavaScript中的对象复制(Object Clone)
var array = [1,2,3,4,5]; var another_array = array; another_array[2] = 5; alert(array[2]); // 因为没有复制,所以影响到了原数组的值 var another_array = array.slice(); another_array[3] = 5; alert(array[3]); // 复制后则不会影响原数组
Javascritp的Array有两个拼写很像的方法:slice
和splice
。
slice
: 用于数组的Shallow Copysplice
: 用于修改数组自身,添加或修改元素TODO
由于数组是一个很基本的数据类型,Array的一些方法也可以用于一些array-like Object。
比如:
Array.prototype.slice.call(nodes);
一个网络上出现过的问题,如何把一个NodeList转换为数组。下面的示例可以说明和回答这个问题:
links = document.getElementsByTagName('a'); links.toString(); // "[object NodeList]" links instanceof Array ; // false links_array = Array.prototype.slice.call(links); links_array instanceof Array ; // true
array.forEach(callback, this)
: iterate each element
array.every(callback, this)
: return false until the one return falsearray.some(callback, this)
: return true until the one return truearray.filter(callback, this)
: create a new Array by filter callbackarray.map(callback, this)
: create a new Array by map callback
array.reduce(callback, initialValue)
array.reduceRight(callback, initialValue)
a = ['a', 'b', 'c']; Object.keys(a); // ["0", "1", "2"] a["1"]; // 'b'
可以认为Array实质上是一个预先绑定了一组方法的特殊的Object。该Object通过length
属性储存数组长度。
这样一来,下面的用法也就很容易解释了。
a = ['a', 'b', 'c']; a[7] = 'g'; a; // ["a", "b", "c", undefined × 4, "g"] a.length -= 2; a; // ["a", "b", "c", undefined × 3]