前端工程师手册

数组的操作

NodeList

NodeList看起来像一个Array(数组),你可以使用中括号来访问他们的节点,而且你还可以通过length属性知道它有多少元素。但是它并没有实现Array的所有接口,因此使用 $$(‘*’).forEach 会返回错误,在JavaScript的世界里,有一堆看起来像Array但其实不是的对象。如function中的arguments对象。因此在他们身上通过call和apply来应用数组的方法是非常有用的。

简单的将他们转换为数组的方法, 比如函数的参数arguments:

function func() {
    var args = Array.prototype.slice.call(arguments);
    // or 
    var args = [].slice.call(arguments);
}

基本操作

常规的构造方法是循环遍历赋值,取值一般直接使用索引。常用的方法有:

  • push(): Adds one or more elements to the end of an array and returns the new length of the array.
  • pop(): Removes the last element from an array and returns that element.
  • shift(): Removes the first element from an array and returns that element.
  • reverse(): Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first.
  • sort(): Sorts the elements of an array in place and returns the array.
  • splice(): Adds and/or removes elements from an array.
  • unshift(): Adds one or more elements to the front of an array and returns the new length of the array.

向数组中插入指定元素

  • 使用索引值: 插入或替换元素
  • push: 末尾添加元素
  • unshift: 首部添加元素

特殊的,要提到一个splice函数,使用方法:

array.splice(start, deleteCount[, item1[, item2[, ...]]])

参数需要注意一下:

  • start: 开始删除的位置
  • deleteCount: 删除的个数
  • [, item1[, item2[, ...]]]: 替换的元素, 如果start超过了数组长度,实际上就是追加的效果,删除的元素小于添加的元素时候,也是追加效果。

删除数组中指定元素

删除首尾的方式是使用:popshift

但是如果我们要删除特殊的指定元素,先要获取到指定元素的下标,然后使用splice进行替换。

ES5标准中新增的方法

  • forEach (js v1.6)
  • map (js v1.6)
  • filter (js v1.6)
  • some (js v1.6)
  • every (js v1.6)
  • indexOf (js v1.6)
  • lastIndexOf (js v1.6)
  • reduce (js v1.8)
  • reduceRight (js v1.8)

对于让人失望很多次的IE6-IE8浏览器,Array原型扩展可以实现以上全部功能,所以也就有了ES5-shim项目。马上都要到ES6得节奏了,这些再不熟悉就别做前端了。

forEach

简化遍历的方法,使用起来是这样: arr.forEach(callback[, thisArg])。callback默认带有三个参数:

  • currentValue
  • index
  • array

thisArg是可选参数,代表可选的上下文参数(改变回调函数里面的this指向).如果这第2个可选参数不指定,则使用全局对象代替(在浏览器是为window),严格模式下甚至是undefined.

注意: 和使用for循环遍历的区别是, forEach不会遍历纯粹的没定义的元素, 比如:

var arr = [1,2,,4];

arr.forEach(console.log);
for (var i = 0, len = arr.length; i < len; i++) {
    console.log(arr[i]);
}

every

按照条件判断数组是否符合要求的作用,返回的是Boolean值,它会用回调函数去遍历所有的数组元素,一般需要制定return的条件。如不指定,默认返回false。找出所有满足的情况,不满足就退出执行。返回值只要是弱等于== true/false就可以了,而非非得返回 === true/false.

some

按照条件判断数组是否符合要求的作用,返回的是Boolean值,它会用回调函数去遍历所有的数组元素,只要有符合的,就会返回true。如果回调函数不指定return值,默认返回false。效果就和forEach类似了。返回值只要是弱等于== true/false就可以了,而非非得返回 === true/false.

fliter

过滤,筛选的作用。返回的是一个新数组,根据回调函数去判断筛选元素。返回值只要是弱等于== true/false就可以了,而非非得返回 === true/false.

map

映射的作用,将原数组的每个元素通过回调方法映射,返回一个同样大小的新数组。

var data = [1, 2, 3, 4];

var arrayOfSquares = data.map(function (item) {
  return item * item;
});

alert(arrayOfSquares); // 1, 4, 9, 16

reduce

用法接近于迭代,递归。语法为:array.reduce(callback[, initialValue]).这个方法是ES5.1之后提出的,算是比上面的方法都新一点。

callback函数接受4个参数:之前值、当前值、索引值以及数组本身。initialValue参数可选,表示初始值。若指定,则当作最初使用的previous值;如果缺省,则使用数组的第一个元素作为previous初始值,同时current往后排一位,相比有initialValue值少一次迭代。

var sum = [1, 2, 3, 4].reduce(function (previous, current, index, array) {
    console.log(previous, current, index, array);
    return previous + current;
});
console.log(sum); // 10

如果initialValue不存在,那么索引就从2开始,以后每次传递的previous就是上一个函数return的值。

如果initialValue存在,那么传入的initialValue就作为第一次的previous值。

reduceRight

reduceRightreduce相比,语法类似:array.reduceRight(callback[, initialValue])

差别在于reduceRight是从数组的末尾开始的。

参考资料