开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情
数组实例的 fill()
`fill` 方法使用给定值,填充一个数组。
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
上面代码表明,`fill` 方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。
`fill` 方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。
['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']
上面代码表示,`fill` 方法从 1 号位开始,向原数组填充 7,到 2 号位之前结束。
注意:如果填充的类型为对象,那么被赋值的是同一个内存地址的对象,而不是深拷贝对象。
let arr = new Array(3).fill({name: "Mike"});
arr[0].name = "Ben";
arr
// [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}]
let arr = new Array(3).fill([]);
arr[0].push(5);
arr
// [[5], [5], [5]]
数组实例的 entries(),keys() 和 values()
ES6 提供三个新的方法 —— `entries()`,`keys()` 和 `values()` —— 用于遍历数组。它们都返回一个遍历器对象(详见 《Iterator》 一章),可以用 for...of 循环进行遍历,唯一的区别是 `keys()` 是对键名的遍历、`values()` 是对键值的遍历,`entries()` 是对键值对的遍历。
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
如果不使用 for...of 循环,可以手动调用遍历器对象的 `next` 方法,进行遍历。
let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']
数组实例的 includes()
`Array.prototype.includes` 方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的 `includes` 方法类似。ES2016 引入了该方法。
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
该方法的第二个参数表示搜索的起始位置,默认为 0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为 -4,但数组长度为 3),则会重置为从 0 开始。
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
没有该方法之前,我们通常使用数组的 `indexOf` 方法,检查是否包含某个值。
if (arr.indexOf(el) !== -1) {
// ...
}
`indexOf` 方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于 -1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对 NaN 的误判。
[NaN].indexOf(NaN)
// -1
`includes` 使用的是不一样的判断算法,就没有这个问题。
[NaN].includes(NaN)
// true
下面代码用来检查当前环境是否支持该方法,如果不支持,部署一个简易的替代版本。
const contains = (() =>
Array.prototype.includes
? (arr, value) => arr.includes(value)
: (arr, value) => arr.some(el => el === value)
)();
contains(['foo', 'bar'], 'baz'); // => false
另外,Map 和 Set 数据结构有一个 `has` 方法,需要注意与 `includes` 区分。
- Map 结构的 `has` 方法,是用来查找键名的,比如 Map.prototype.has(key)、WeakMap.prototype.has(key)、Reflect.has(target, propertyKey)。
- Set 结构的 `has` 方法,是用来查找值的,比如 Set.prototype.has(value)、WeakSet.prototype.has(value)。