7

之前看到知乎上的这道题:如何不使用loop循环,创建一个长度为100的数组,并且每个元素的值等于它的下标?,在这个问题里面题主提到,他写了这么一段代码:

'use strict'
let arr = Array(100).map( (item,idx) =>  idx)

结果arr是一个有100个空位的数组:
图片描述
这说明Array.prototype.map()会跳过空位元素嘛。

然后我在下面的答案里看到这么一条:

Array.from(new Array(100), (item, idx) => idx)

//or the alternative
Array.from({length: 5}, (item, idx) => idx)

我本来是觉得,这个肯定也不行嘛,这俩都是用Array构造函数新建了一个全是空位的数组嘛,怎么会不一样呢?结果试了一下之后发现居然成功地得到了数组。我开始怀疑Array.from的map函数的实现和Array.prototype.map有不一样的地方。再加上MDN的文档也来捣乱:

Array.from(arrayLike[, mapFn[, thisArg]])

#arrayLike

An array-like or iterable object to convert to an array.

#mapFn

Optional. Map function to call on <every element of the array>.

#thisArg

Optional. Value to use as this when executing mapFn.

在这里mapFn下面明确地指出mapFn会调用every element of the array.

而在map函数那边:

callback is invoked only for indexes of the array which have assigned values, including undefined. It is not called for missing elements of the array.

明确说明会跳过空位元素,所以我就想是不是这俩家伙的map方法本身不一致。

当然结论并没有这么厉害 Orz...后来我偶然间发现原来是因为Array.from()方法会把数组的空位转为undefined.也就是说数组空位元素的处理和map方法的实现是无关的。


数组空位元素的处理

  • forEach(), filter(), every()some()都会跳过空位。

  • map()会跳过空位,但会保留这个值

  • join()toString()会将空位视为undefined,而undefinednull会被处理成空字符串

// forEach方法
[,'a'].forEach((x,i) => log(i)); // 1

// filter方法
['a',,'b'].filter(x => true) // ['a','b']

// every方法
[,'a'].every(x => x==='a') // true

// some方法
[,'a'].some(x => x !== 'a') // false

// map方法
[,'a'].map(x => 1) // [,1]

// join方法
[,'a',undefined,null].join('#') // "#a##"

// toString方法
[,'a',undefined,null].toString() // ",a,,"

ES6则是明确将空位转为undefined,Array.from方法会将数组的空位转为undefined,也就是说,这个方法不会忽略空位:

Array.from(['a',,'b'])
// [ "a", undefined, "b" ]

扩展运算符(...)也会将空位转为undefined:

[...['a',,'b']]
// [ "a", undefined, "b" ]

for...of循环也会遍历空位:

let arr = [, ,];
for (let i of arr) {
  console.log(1);
}
// 1
// 1

entries()keys()values()find()findIndex()会将空位处理成undefined:

// entries()
[...[,'a'].entries()] // [[0,undefined], [1,"a"]]

// keys()
[...[,'a'].keys()] // [0,1]

// values()
[...[,'a'].values()] // [undefined,"a"]

// find()
[,'a'].find(x => true) // undefined

// findIndex()
[,'a'].findIndex(x => true) // 0

参考:阮一峰ES2015


dustin__
614 声望50 粉丝

前端


下一篇 »
DomReady