JavaScript集合引用类型——Array
创建数组
① 使用 Array 构造函数
- 在使用 Array 构造函数时,也可以省略 new 操作符;
1 | let colors = new Array(); |
- 如果知道数组中元素的数量,那么可以给构造函数传入一个数值,然后 length 属性就会被自动创建并设置为这个值:
1 | let colors = new Array(15); |
- 也可以给 Array 构造函数传入要保存的元素:
1 | let colors = new Array("red", "blue", "green"); |
② 使用数组字面量(array literal)表示法:
1 | let colors = ["red", "blue", "green"]; // 创建一个包含 3 个元素的数组 |
③ from()
from()用于将类数组结构转换为数组实例;
Array.from()的第一个参数是一个类数组对象,即任何可迭代的结构,或者有一个 length 属性和可索引元素的结构:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40// 字符串会被拆分为单字符数组
console.log(Array.from("Matt")); // ["M", "a", "t", "t"]
// 可以使用 from()将集合和映射转换为一个新数组
const m = new Map().set(1, 2)
.set(3, 4);
const s = new Set().add(1)
.add(2)
.add(3)
.add(4);
console.log(Array.from(m)); // [[1, 2], [3, 4]]
console.log(Array.from(s)); // [1, 2, 3, 4]
// Array.from()对现有数组执行浅复制
const a1 = [1, 2, 3, 4];
const a2 = Array.from(a1);
console.log(a1); // [1, 2, 3, 4]
alert(a1 === a2); // false
// 可以使用任何可迭代对象
const iter = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
yield 4;
}
};
console.log(Array.from(iter)); // [1, 2, 3, 4]
// arguments 对象可以被轻松地转换为数组
function getArgsArray() {
return Array.from(arguments);
}
console.log(getArgsArray(1, 2, 3, 4)); // [1, 2, 3, 4]
// from()也能转换带有必要属性的自定义对象
const arrayLikeObject = {
0: 1,
1: 2,
2: 3,
3: 4,
length: 4
};
console.log(Array.from(arrayLikeObject)); // [1, 2, 3, 4]Array.from()还接收第二个可选的映射函数参数;
- 这个函数可以直接增强新数组的值,而无须像调用 Array.from().map()那样先创建一个中间数组;
还可以接收第三个可选参数,用于指定映射函数中 this 的值;
1 | const a1 = [1, 2, 3, 4]; |
④ of()
- Array.of()可以把一组参数转换为数组
- 用于替代在 ES6之前常用的 Array.prototype.slice.call(arguments),一种异常笨拙的将 arguments 对象转换为数组的写法:
1 | console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4] |
数组空位
- 使用数组字面量初始化数组时,可以使用一串逗号来创建空位(hole);
- ECMAScript 会将逗号之间相应索引位置的值当成空位;
1 | const options = [,,,,,]; // 创建包含 5 个元素的数组 |
- ES6 新增方法普遍将这些空位当成存在的元素,只不过值为 undefined:
1 | const options = [1,,,,5]; |
数组索引
- 要取得或设置数组的值,需要使用中括Ձ并提供相应值的数字索引:
- 如果把一个值设置给超过数组最大索引的索引,就像示例中的 colors[3],则数组长度会自动扩展到该索引值加 1;
- 数组中最后一个元素的索引始终是 length - 1;
- 数组最多可以包含 4294967295 个元素;
1 | let colors = ["red", "blue", "green"]; // 定义一个字符串数组 |
检测数组
- ECMAScript 提供了 Array.isArray()方法,的目的就是确定一个值是否为数组,而不用管它是在哪个全局执行上下文中创建的;
迭代器方法
- 在 ES6 中,Array 的原型上暴露了 3 个用于检索数组内容的方法:keys()、values()和entries();
- keys()返回数组索引的迭代器;
- values()返回数组元素的迭代器;
- entries()返回索引/值对的迭代器;
1 | const a = ["foo", "bar", "baz", "qux"]; |
复制和填充方法
- 批量复制方法 copyWithin();
- 填充数组方法 fill();
- 这两个方法的函数签名类似,都需要指定既有数组实例上的一个范围,包含开始索引,不包含结束索引;
fill()
- fill()方法可以向一个已有的数组中插入全部或部分相同的值;
- 开始索引用于指定开始填充的位置,它是可选的。如果不提供结束索引,则一直填充到数组末尾;
- 负值索引从数组末尾开始计算,也可以将负索引想象成数组长度加上它得到的一个正索引;
- fill()默认忽略超出数组边界、零长度及方向相反的索引范围;
1 | const zeroes = [0, 0, 0, 0, 0]; |
copyWithin()
- copyWithin()会按照指定范围ุ复制数组中的部分内容,然后将它们插入到指定索引开始的位置;
- copyWithin()静默忽略超出数组边界、零长度及方向相反的索引范围:
1 | let ints, |
转换方法
- 所有对象都有 toLocaleString()、toString()和 valueOf()方法;
- 在调用数组的 toLocaleString()方法时,会得到一个以逗号分隔的数组值的字符串;
1 | let colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组 |
- 首先是被显式调用的 toString()和 valueOf()方法,它们分别返回了数组的字符串表示,所有字符串组合起来,以逗号分隔。最后一行代码直接用 alert()显示数组,因为 alert()期待字符串,所以会在后台调用数组的 toString()方法,从而得到跟前面一样的结果;
1 | let person1 = { |
- 如果数组中某一项是null或undefined,则在join()、toLocaleString()、toString()、valueOf()返回的结果中会以空字符串表示
栈方法
1 | let colors = new Array(); // 创建一个数组 |
队列方法
- 使用shift()和 push(),可以把数组当成队列来使用:
1 | let colors = new Array(); // 创建一个数组 |
- 使用 unshift()和 pop(),可以在相反方向上模拟队列:
1 | let colors = new Array(); // 创建一个数组 |
排序方法
1 | let values = [1, 2, 3, 4, 5]; |
- sort()会在每一项上调用 String()转型函数,然后比较字符串来决定顺序。
- 即使数组的元素都是数值,也会先把数组转换为字符串再比较、排序。
1 | //一开始数组中数值的顺序是正确的,但调用 sort()会按照这些数值的字符串形式重新排序。 |
- sort()方法可以接收一个比较函数
- 比较函数接收两个参数:
- 如果第一个参数应该排在第二个参数前面,就返回负值;* 如果两个参数相等,就返回 0;
- 如果第一个参数应该排在第二个参数后面,就返回正值;
1 | function compare(value1, value2) { |
- 比较函数还可简写为一个箭头函数:
1 | let values = [0, 1, 5, 10, 15]; |
操作方法
concat()方法
- 可以在现有数组全部元素基础上创建一个新数组;
- 原理:它首先会创建一个当前数组的副本,然后再把它的参数添加到副本末尾,最后返回这个新构建的数组;
1 | let colors = ["red", "green", "blue"]; |
- 打平数组参数的行为可以重写,方法是在参数数组上指定一个特殊的符号:Symbol.isConcatSpreadable;
1 | let colors = ["red", "green", "blue"]; |
slice()方法
- 用于创建一个包含原有数组中一个或多个元素的新数组,操作不影响原始数组;
- 接收一个或两个参数:返回元素的开始索引和结束索引;
- 如果只有一个参数,则 slice()会返回该索引到数组末尾的所有元素;
- 如果有两个参数,则 slice()返回从开始索引到结束索引对应的所有元素,其中不包含结束索引对应的元素;
1 | let colors = ["red", "green", "blue", "yellow", "purple"]; |
splice()方法
- 在数组中间插入元素;
- 删除:需要给 splice()传 2 个参数:要删除的第一个元素的位置和要删除的元素数量;
- 插入:需要给 splice()传 3 个参数:开始位置、0(要删除的元素数量)和要插入的元素,可以在数组中指定的位置插入元素,第三个参数之后还可以传第四个、第五个参数,乃至任意多
个要插入的元素; - 替换:splice()在删除元素的同时可以在指定位置插入新元素,同样要传入 3 个参数:开始位置、要删除元素的数量和要插入的任意多个元素;
1 | let colors = ["red", "green", "blue"]; |
搜索和位置方法
- ECMAScript 提供两类搜索数组的方法:按严格相等搜索和按断言函数搜索;
严格相等
1 | let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1]; |
断言函数
断言函数接收 3 个参数:元素、索引和数组本身;
- 元素是数组中当前଼索的元素;
- 索引是当前元素的索引;
- 数组就是正在଼索的数组
find()和 findIndex()方法使用了断言函数:
- 这两个方法都从数组的最小索引开始;
- find()返回第一个匹配的元素;
- findIndex()返回第一个匹配元素的索引
- 这两个方法也都接收第二个可选的参数,用于指定断言函数内部 this 的值。
1 | const people = [ |
迭代方法
1 | let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1]; |
归并方法
1 | let values = [1, 2, 3, 4, 5]; |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 姚永坤的小窝!
评论