所有数组上的新方法
ES6 延续了 ES5 的工作,为数组增加了几个新方法。find() 与 findIndex() 方法是为了让开发者能够处理包含任意值的数组,而 fill() 与 copyWithin() 方法则是受到了类型化数组(typed arrays)的启发。类型化数组是在 ES6 中引入的,只允许包含数值类型的值。
find() 与 findIndex() 方法
在 ES5 之前,检索数组是件麻烦事,因为没有对应的原生方法可用。ES5 增加了 indexOf() 与 lastIndexOf() 方法,从而允许开发者在数组中查找特定值。 这虽然是很大的进步,但依然受到了一些限制,因为你每次只能用它们来查找某个特定值。例如,若想在一系列的数中间查找第一个偶数,你必须自己写代码来实现这个意图。而 ES6 引入了 find() 与 findIndex() 方法,从而解决了这方面的问题。
find() 与 findIndex() 方法均接受两个参数:一个回调函数、一个可选值用于指定回调函数内部的 this。该回调函数可接收三个参数:数组的某个元素、该元素对应的索引位置、以及该数组自身,这与 map() 和 forEach() 方法的回调函数所用的参数一致。该回调函数应当在给定的元素满足你定义的条件时返回 true,而 find() 与 findIndex() 方法均会在回调函数第一次返回 true 时停止查找。
二者唯一的区别是:find() 方法会返回匹配的值,而 findIndex() 方法则会返回匹配位置的索引。这里有个示例:
let numbers = [25, 30, 35, 40, 45];
console.log(numbers.find(n => n > 33)); // 35
console.log(numbers.findIndex(n => n > 33)); // 2
这段代码使用了 find() 与 findIndex() 方法在 numbers 数组中查找第一个大于 33 的元素,前者返回 35,而后者返回 2(也就是 35 这个元素在数组中的索引值) 。
find() 与 findIndex() 方法在查找满足特定条件的数组元素时非常有用。但若想查找特定值,则使用 indexOf() 与 lastIndexOf() 方法会是更好的选择。
fill() 方法
fill() 方法能使用特定值填充数组中的一个或多个元素。当只使用一个参数的时候,该方法会用该参数的值填充整个数组,例如:
let numbers = [1, 2, 3, 4];
numbers.fill(1);
console.log(numbers.toString()); // 1,1,1,1
此代码中的 numbers.fill(1) 调用将 numbers 数组中的所有元素都填充为 1。若你不想改变数组中的所有元素,而只想改变其中一部分,那么可以使用可选的起始位置参数与结束位置参数(不包括结束位置的那个元素),就像这样:
let numbers = [1, 2, 3, 4];
numbers.fill(1, 2);
console.log(numbers.toString()); // 1,2,1,1
numbers.fill(0, 1, 3);
console.log(numbers.toString()); // 1,0,0,1
当进行 numbers.fill(1,2) 调用时,第二个参数 2 指定从数组索引值为 2 的元素(即数组的第 3 个元素)开始填充,而此时没有指定第三个参数,因此结束位置默认为 numbers 数组的长度,意味着该数组的最后两个元素会被填充为 1。而 numbers.fill(0, 1, 3) 调用则将该数组索引值为 1 与 2 的元素填充为 0 。在调用 fill() 方法时指定第二个和第三个参数,允许你一次性填充数组中多个元素,避免改写整个数组。
如果提供的起始位置或结束位置为负数,则它们会被加上数组的长度来算出最终的位置。例如:将起始位置指定为 -1,就等于是 array.length - 1,这里的 array 指的是 fill() 方法所要处理的数组。 |
copyWithin() 方法
copyWithin() 方法与 fill() 类似,可以一次性修改数组的多个元素。不过, 与 fill() 使用单个值来填充数组不同,copyWithin() 方法允许你在数组内部复制自身元素。为此你需要传递两个参数给 copyWithin() 方法:从什么位置开始进行填充,以及被用来复制的数据的起始位置索引。
例如,将数组的前两个元素复制到数组的最后两个位置,你可以这么做:
let numbers = [1, 2, 3, 4];
// paste values into array starting at index 2
// copy values from array starting at index 0
numbers.copyWithin(2, 0);
console.log(numbers.toString()); // 1,2,1,2
这段代码从 numbers 数组索引值为 2 的元素开始进行填充,因此索引值为 2 与 3 的元素都会被覆盖;调用 copyWithin() 方法时将第二个参数指定为 0,表示被复制的数据从索引值为 0 的元素开始,一直到没有元素可供复制为止。
默认情况下,copyWithin() 方法总是会一直复制到数组末尾,不过你还可以提供一个可选参数来限制到底有多少元素会被覆盖。这第三个参数指定了复制停止的位置(不包含该位置自身),这里有个范例:
let numbers = [1, 2, 3, 4];
// paste values into array starting at index 2
// copy values from array starting at index 0
// stop copying values when you hit index 1
numbers.copyWithin(2, 0, 1);
console.log(numbers.toString()); // 1,2,1,4
在这个例子中,因为可选的结束位置参数被指定为 1,于是只有索引值为 0 的元素被复制了,而该数组的最后一个元素并没有被修改。
类似于 fill() 方法,如果你向 copyWithin() 方法传递负数参数,数组的长度会自动被加到该参数的值上,以便算出正确的索引位置。 |
fill() 与 copyWithin() 方法初看起来不是那么有用,因为它们起源于类型化数组的需求,而出于功能一致性的目的才被添加到常规数组上。不过,接下来的小节你就会学到如何用类型化数组来按位操作数值,此时这两个方法就会变得非常有用了。