在ES6中,数组新增了多项扩展,极大提高了操作数组的便捷性。以下是一些常用的扩展及其用法:
1. Array.from()
用于从类数组对象或迭代器创建一个新的数组实例。这个方法可以接受两个参数:
-
source (来源):
这是必须的参数,可以是一个类数组对象(如arguments对象,DOM的NodeList对象等)或者任何可迭代对象(如字符串、Map或Set等)。Array.from()将会把这个对象转换成数组。 -
mapFn(映射函数):
这是可选的参数,如果提供了此函数,则会应用于目标数组中的每个元素,并且新数组中对应的元素将是调用该函数的结果。映射函数会被作为Array.prototype.map()
的回调函数来使用,它接收三个参数:当前处理的元素值、元素的索引以及源数组。
javascript
// 使用 Array.from() 从字符串创建数组
const str = 'hello';
const arr = Array.from(str);
console.log(arr); // 输出: ['h', 'e', 'l', 'l', 'o']
// 使用 Array.from() 并提供映射函数
const numArr = [1, 2, 3, 4, 5];
const squaredArr = Array.from(numArr, x => x * x);
console.log(squaredArr); // 输出: [1, 4, 9, 16, 25]
在这个例子中,第一个Array.from()
调用将字符串转换为字符数组,而第二个则创建了一个新数组,其中包含了原数组元素的平方值。
2. Array.of()
Array.of()
是 JavaScript 中的一个静态方法,用于从零个或多个给定的参数创建一个新的 Array
实例。这个方法非常直接,主要用于那些需要将几个单独的值组合成一个数组的情况。
基本语法
javascript
Array.of(item1[, item2[, ...[, itemN]]])
参数
item1, item2, ..., itemN
:这些是要包含在新数组中的项。可以是任意类型的数据,包括undefined
,null
, 对象, 字符串等等。
返回值
- 返回的新数组包含了传入的所有项。
示例
以下是一些使用 Array.of()
的示例:
javascript
// 创建一个只有一个数字的数组
let singleItemArray = Array.of(10);
console.log(singleItemArray); // 输出: [10]
// 创建一个包含多个混合类型的数组
let mixedArray = Array.of('hello', 42, true);
console.log(mixedArray); // 输出: ['hello', 42, true]
// 创建一个空数组
let emptyArray = Array.of();
console.log(emptyArray); // 输出: []
与字面量数组的区别
使用 Array.of()
和直接使用方括号创建数组(即字面量数组)的主要区别在于处理单个参数的方式:
javascript
// 使用字面量方式创建数组
let singleNumberLiteral = [10]; // 结果是一个包含单个元素的数组: [10]
// 使用 Array.of() 创建数组
let singleNumberArrayOf = Array.of(10); // 同样结果是一个包含单个元素的数组: [10]
// 使用字面量方式创建单元素数组与直接创建单值
let justANumber = [10,]; // 也会得到一个数组: [10], 但是通常不需要逗号
// 使用 Array.of() 时,即使只传递一个参数,也会创建一个数组
let justANumberWithArrayOf = Array.of(10); // 结果是一个数组: [10]
总的来说,Array.of()
可以确保即使只传递一个参数也能正确地返回一个数组,而在方括号字面量的情况下,单个值不会自动变成数组的一部分,除非明确地将其放入方括号内。
3. find()
和 findIndex()
在 JavaScript 中,Array.prototype.find()
和 Array.prototype.findIndex()
都是用来查找数组中满足特定条件的元素的方法,但它们返回的结果有所不同。
Array.prototype.find()
find()
方法会遍历数组中的每个元素,直到找到第一个使提供的函数返回 true
的元素为止,然后返回该元素。如果没有找到符合条件的元素,则返回 undefined
。
语法
javascript
array.find(callback[, thisArg])
参数
callback(element[, index[, array]])
: 必需。一个函数,对于数组中的每个元素都会调用一次。该函数应该返回一个布尔值。element
: 当前遍历到的数组元素。index
: 当前遍历到的元素的索引。array
: 调用find
的数组。
thisArg
: 可选。执行回调函数时使用的this
值。
示例
javascript
const numbers = [1, 2, 3, 4, 5];
// 寻找第一个大于 3 的元素
const foundElement = numbers.find((element, index, arr) => {
return element > 3;
});
console.log(foundElement); // 输出: 4
Array.prototype.findIndex()
findIndex()
方法同样会遍历数组中的每个元素,直到找到第一个使提供的函数返回 true
的元素为止,然后返回该元素的索引。如果没有找到符合条件的元素,则返回 -1
。
语法
javascript
array.findIndex(callback[, thisArg])
参数
callback(element, index, array)
: 必需。一个函数,对于数组中的每个元素都会调用一次。该函数应该返回一个布尔值。element
: 当前遍历到的数组元素。index
: 当前遍历到的元素的索引。array
: 调用findIndex
的数组。
thisArg
: 可选。执行回调函数时使用的this
值。
示例
javascript
const numbers = [1, 2, 3, 4, 5];
// 寻找第一个大于 3 的元素的索引
const foundIndex = numbers.findIndex((element, index, arr) => {
return element > 3;
});
console.log(foundIndex); // 输出: 3
find()
返回的是满足条件的第一个元素本身。findIndex()
返回的是满足条件的第一个元素的索引。
这两个方法都可以根据需要定制查找逻辑,并且在找不到匹配项时有不同的默认返回值(find()
返回 undefined
,findIndex()
返回 -1
)。
4. includes()
Array.prototype.includes()
方法用于检查数组中是否包含指定的元素,根据情况返回 true
或 false
。这是一个非常直观且常用的方法,可以简化数组中元素的查找操作。
语法
javascript
array.includes(searchElement[, fromIndex])
参数
searchElement
: 必需。要查找的元素。fromIndex
: 可选。开始搜索的位置,默认从数组的第一个元素开始(索引为0
)。如果为负数,则会从数组的末尾开始向前计数。
返回值
- 如果数组中存在至少一个与
searchElement
相等的元素,则返回true
;否则返回false
。
示例
下面是一些使用 includes()
方法的例子:
javascript
const numbers = [1, 2, 3, 4, 5];
// 检查数组中是否存在元素 3
console.log(numbers.includes(3)); // 输出: true
// 检查数组中是否存在元素 6
console.log(numbers.includes(6)); // 输出: false
// 从索引 2 开始查找元素 3
console.log(numbers.includes(3, 2)); // 输出: true
// 从索引 3 开始查找元素 3
console.log(numbers.includes(3, 3)); // 输出: false
// 从索引 -1 (相当于数组最后一个元素) 开始向前查找元素 5
console.log(numbers.includes(5, -1)); // 输出: true
// 从索引 -2 开始向前查找元素 4
console.log(numbers.includes(4, -2)); // 输出: true
注意事项
includes()
方法会使用严格的相等性比较 (===
) 来判断元素是否相等。- 如果数组很大,从某个索引开始搜索可能会提高效率。
includes()
方法可以很好地处理null
和undefined
的检查,因为这些值会直接通过严格相等性比较进行匹配。
兼容性
includes()
方法是在 ECMAScript 2016 (ES7) 中引入的,因此在现代浏览器和环境中普遍可用。如果你需要支持旧版本的浏览器或其他环境,可能需要使用其他方法(如 indexOf()
)来实现类似的功能。例如:
javascript
if (!Array.prototype.includes) {
Array.prototype.includes = function(searchElement, fromIndex) {
return this.indexOf(searchElement, fromIndex) !== -1;
};
}
这段代码可以在不支持 includes()
的环境中提供一个回退的实现。
5. fill()
Array.prototype.fill()
方法用于将数组的所有元素填充为一个固定的值。这是一个非常实用的方法,特别是在初始化数组或设置所有元素为相同的初始值时。
语法
javascript
array.fill(value[, start[, end]])
参数
value
: 必需。用来填充数组的值。可以是任何类型的数据,包括数字、字符串、对象等。start
: 可选。开始填充的索引位置,默认为0
(即从数组的第一个元素开始)。end
: 可选。停止填充的索引位置,默认为数组的长度(即填充整个数组)。注意,这个位置是不包括在内的。
返回值
- 返回被填充后的数组。
示例
下面是一些使用 fill()
方法的例子:
javascript
// 创建一个包含五个元素的数组,并填充为 0
let zeros = new Array(5).fill(0);
console.log(zeros); // 输出: [0, 0, 0, 0, 0]
// 创建一个数组并填充为 'x',从索引 1 开始
let letters = ['a', 'b', 'c', 'd', 'e'];
letters.fill('x', 1);
console.log(letters); // 输出: ['a', 'x', 'x', 'x', 'x']
// 创建一个数组并填充为 'y',从索引 1 到索引 3(不包括)
let letters2 = ['a', 'b', 'c', 'd', 'e'];
letters2.fill('y', 1, 3);
console.log(letters2); // 输出: ['a', 'y', 'y', 'd', 'e']
注意事项
fill()
方法会修改原始数组。- 如果
start
或end
参数不在数组的有效索引范围内,则会忽略它们。 - 如果
start
大于end
,则fill()
不会对数组做任何改变。 fill()
方法适用于任何可以被索引访问的数据结构,不仅限于数组。
兼容性
fill()
方法是在 ECMAScript 2015 (ES6) 中引入的,因此在现代浏览器和环境中普遍可用。如果你需要支持旧版本的浏览器或其他环境,可能需要使用其他方法手动实现类似的功能。例如,可以使用循环来填充数组:
javascript
function fill(array, value, start = 0, end = array.length) {
for (let i = start; i < end; i++) {
array[i] = value;
}
return array;
}
// 使用自定义 fill 函数
let customFillArray = [1, 2, 3, 4, 5];
fill(customFillArray, 'z', 1, 4);
console.log(customFillArray); // 输出: [1, 'z', 'z', 'z', 5]
这种方法可以在不支持 fill()
的环境中提供一个回退实现。
6. copyWithin()
在数组内部复制元素到指定位置。
javascript
const arr = [1, 2, 3, 4];
arr.copyWithin(0, 2);
console.log(arr); // [3, 4, 3, 4]
7. entries()
Array.prototype.entries()
方法用于返回一个迭代器对象,该对象包含了数组中每个元素的索引和值。这个方法通常用于需要同时访问数组索引和值的场景。
语法
javascript
array.entries()
返回值
- 一个迭代器对象,每次迭代返回一个数组
[index, value]
,其中index
是数组元素的索引,value
是数组元素的值。
示例
下面是一些使用 entries()
方法的例子:
javascript
const numbers = [1, 2, 3, 4, 5];
// 使用 entries() 遍历数组
for (const [index, value] of numbers.entries()) {
console.log(`索引 ${index}: 值 ${value}`);
}
// 输出:
// 索引 0: 值 1
// 索引 1: 值 2
// 索引 2: 值 3
// 索引 3: 值 4
// 索引 4: 值 5
使用场景
entries()
方法特别适合用于需要同时访问数组索引和值的情况,比如:
-
打印数组的索引和值:
javascriptconst fruits = ['apple', 'banana', 'cherry']; for (const [index, fruit] of fruits.entries()) { console.log(`${index}: ${fruit}`); }
-
更新数组中的元素:
javascriptconst scores = [10, 20, 30, 40]; for (const [index, score] of scores.entries()) { scores[index] = score + 5; } console.log(scores); // 输出: [15, 25, 35, 45]
-
创建 Map 对象:
javascriptconst keyValues = [[1, 'one'], [2, 'two'], [3, 'three']]; const map = new Map(keyValues.entries()); console.log(map); // 输出: Map(3) { 1 => "one", 2 => "two", 3 => "three" }
注意事项
entries()
返回的是一个迭代器对象,可以用于for...of
循环。- 如果数组中有
undefined
或null
的元素,entries()
依然会返回这些值及其对应的索引。 entries()
方法不会跳过稀疏数组中的空位(即未定义的索引),而是会返回[index, undefined]
。
兼容性
entries()
方法是在 ECMAScript 2015 (ES6) 中引入的,因此在现代浏览器和环境中普遍可用。如果你需要支持旧版本的浏览器或其他环境,可能需要使用其他方法来实现类似的功能。例如,可以手动创建一个迭代器对象:
javascript
function* manualEntries(array) {
for (let i = 0; i < array.length; i++) {
yield [i, array[i]];
}
}
const numbers = [1, 2, 3, 4, 5];
for (const [index, value] of manualEntries(numbers)) {
console.log(`索引 ${index}: 值 ${value}`);
}
这种方法可以在不支持 entries()
的环境中提供一个回退实现。
8. keys()
Array.prototype.keys()
方法用于返回一个迭代器对象,该对象包含了数组中每个元素的索引。这个方法主要用于获取数组的键(索引),而不是值。
语法
javascript
array.keys()
返回值
- 一个迭代器对象,每次迭代返回数组元素的索引。
示例
下面是一些使用 keys()
方法的例子:
javascript
const numbers = [1, 2, 3, 4, 5];
// 使用 keys() 遍历数组索引
for (const index of numbers.keys()) {
console.log(`索引 ${index}`);
}
// 输出:
// 索引 0
// 索引 1
// 索引 2
// 索引 3
// 索引 4
使用场景
keys()
方法特别适合用于需要仅访问数组索引的情况,比如:
-
打印数组的索引:
javascriptconst fruits = ['apple', 'banana', 'cherry']; for (const index of fruits.keys()) { console.log(`索引 ${index}`); }
-
根据索引更新数组中的元素:
javascriptconst scores = [10, 20, 30, 40]; for (const index of scores.keys()) { scores[index] = scores[index] + 5; } console.log(scores); // 输出: [15, 25, 35, 45]
-
创建 Map 对象,使用索引作为键:
javascriptconst keyValues = [[1, 'one'], [2, 'two'], [3, 'three']]; const map = new Map(keyValues.keys().map((index, i) => [index, keyValues[i][1]])); console.log(map); // 输出: Map(3) { 0 => "one", 1 => "two", 2 => "three" }
注意事项
keys()
返回的是一个迭代器对象,可以用于for...of
循环。- 如果数组中有
undefined
或null
的元素,keys()
依然会返回这些值对应的索引。 keys()
方法不会跳过稀疏数组中的空位(即未定义的索引),而是会正常返回这些索引。
兼容性
keys()
方法是在 ECMAScript 2015 (ES6) 中引入的,因此在现代浏览器和环境中普遍可用。如果你需要支持旧版本的浏览器或其他环境,可能需要使用其他方法来实现类似的功能。例如,可以手动创建一个迭代器对象:
javascript
function* manualKeys(array) {
for (let i = 0; i < array.length; i++) {
yield i;
}
}
const numbers = [1, 2, 3, 4, 5];
for (const index of manualKeys(numbers)) {
console.log(`索引 ${index}`);
}
这种方法可以在不支持 keys()
的环境中提供一个回退实现。
9. values()
Array.prototype.values()
方法用于返回一个迭代器对象,该对象包含了数组中每个元素的值。这个方法主要用于获取数组中的元素值,而不包括其索引。
语法
javascript
array.values()
返回值
- 一个迭代器对象,每次迭代返回数组中的一个元素。
示例
下面是一些使用 values()
方法的例子:
javascript
const numbers = [1, 2, 3, 4, 5];
// 使用 values() 遍历数组值
for (const value of numbers.values()) {
console.log(value);
}
// 输出:
// 1
// 2
// 3
// 4
// 5
使用场景
values()
方法特别适合用于需要仅访问数组值的情况,比如:
-
打印数组的值:
javascriptconst fruits = ['apple', 'banana', 'cherry']; for (const fruit of fruits.values()) { console.log(fruit); }
-
处理数组中的每个元素:
javascriptconst scores = [10, 20, 30, 40]; for (const score of scores.values()) { console.log(score + 5); }
-
创建新的数组或集合:
javascriptconst numbers = [1, 2, 3, 4, 5]; const doubledNumbers = [...numbers.values()].map(n => n * 2); console.log(doubledNumbers); // 输出: [2, 4, 6, 8, 10]
注意事项
values()
返回的是一个迭代器对象,可以用于for...of
循环。- 如果数组中有
undefined
或null
的元素,values()
依然会返回这些值。 values()
方法不会跳过稀疏数组中的空位(即未定义的索引),而是会返回undefined
。
兼容性
values()
方法是在 ECMAScript 2015 (ES6) 中引入的,因此在现代浏览器和环境中普遍可用。如果你需要支持旧版本的浏览器或其他环境,可能需要使用其他方法来实现类似的功能。例如,可以手动创建一个迭代器对象:
javascript
function* manualValues(array) {
for (let i = 0; i < array.length; i++) {
yield array[i];
}
}
const numbers = [1, 2, 3, 4, 5];
for (const value of manualValues(numbers)) {
console.log(value);
}
这种方法可以在不支持 values()
的环境中提供一个回退实现。
最后
这些扩展使数组操作更加灵活和强大,提升了代码的可读性与效率。