第2章 数组
数组是最简单的内存数据结构,几乎所有编程语言都原生支持数组类型,尽管 JS 数组中可以保存不同类型的值,但像其他语言那样,别这么做。另外 JS 中数组的容量是动态的。
1. 添加和删除元素
push 添加元素到末尾,pop 删除末尾元素,unshift 添加元素到首位,shift 删除首位元素。
在任意位置添加或删除元素:splice(start, ?deleteCount, ...items)。
另外 delete 操作符也可以删除数组元素,但别这么做,因为只是删除值,位置还在:
delete numbers[0] 等价于 numbers[0] = undefined
应始终使用 splice、pop 或 shift 来删除数组元素。
2. JS 的数组方法
2.1 ES5
every、some、forEach、map、filter、reduce、slice、join、indexOf、lastIndexOf、reverse、sort、toString、valueOf。
map 如其名,依照给定函数对值进行映射,而 reduce(减小、归纳)依照给定函数规约数组包含的值。
2.2 ES6
@@iterator、copyWithin、entries、keys、values、includes、find、findIndex、fill、Array.from、Array.of
ES6 为 Array 类增加了 @@iterator (迭代器)属性,通过 Symbol.iterator 这个 key 来访问,数组中所有的值都迭代完之后,iterator.next().value 会返回 undefined:
const numbers = [1, 2, 3, 4, 5];
const iterator = numbers[Symbol.iterator]();
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
// ...
另外还增加了三种从数组中得到迭代器的方法,entries、keys、values,直接如同 numbers.entries() 这样获取即可,分别用来迭代键值对、数组索引和保存在数组索引中的值。使用集合、字典、散列表等数据结构时,能够取出键值对是很有用的。
创建数组并初始化值得时候,fill 方法比较好用:
let ones = Array(6).fill(1); // [1, 1, 1, 1, 1, 1]
Array.from(arrayLike[, mapFn[, thisArg]]) 方法从一个类似数组或可迭代对象创建一个新的、浅拷贝的数组实例。
Array.of(element0[, element1[, ...[, element_N_]]]) 用若干个元素创建新的数组实例,和 Array 构造函数的唯一区别是只有一个参数时。
arr.copyWithin(target[, start[, end]]) copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
2.3 排序元素
reverse 算一个。
arr.sort([compareFunction]) 方法默认将元素按照字符串、按照 ASCII 值进行比较。传入自定义的比较函数,返回正数则交换二者位置,一个简单的比较数字的升序函数如下:
function compareNumbers(a, b) {
return a - b;
}
2.4 搜索
indexOf、lastIndexOf 从前或从后开始匹配到的第一个元素的索引或没匹配到就是 -1。
arr.find(callback[, thisArg]) 类似 forEach 和 map 函数那样接收回调函数用于搜索条件满足真实值(可转为true)的元素,找不到就返回 undefined。
findIndex 同理,找不到就返回 -1。
ES7-arr.includes(valueToFind[, fromIndex]) 方法用来判断一个数组是否包含一个指定的值,如果包含则返回 true,否则返回false。
2.5 输出数组为字符串
toString 和 join 默认都是用逗号 ,
分隔。
但 join 可传入指定分隔符,而且还可以连接类数组对象:
function foo(a, b, c) {
var s = Array.prototype.join.call(arguments);
console.log(s); // '1,a,true'
}
foo(1, 'a', true);