wkiwi的博客

JS无法使用Map遍历Array创建的数组

发布时间:4年前热度: 2588 ℃评论数:

此问题是一道面试题


Array(100).map(x=>1)的结果什么,有什么办法创建一个长度为100且元素均为1 的数组


理想情况下Array(100)创建了一个长度为100 的数组,使用map去循环

实际运行情况如下

1615873352470.jpg

map循环压根就没有执行,更别说改到数组内的内容


原理


以下为map的定义和用法

企业微信20210316-135523@2x.png

为了解释上面的现象,我必须介绍一个重要的技术特性。在 JavaScript 内部,数组就是用数字作为键名的对象。比如:

['a', 'b', 'c']

本质上它等于下面的对象:

{ 0: 'a', 1: 'b', 2: 'c', length: 3 }

当访问数组中索引 0 的元素时,实际上访问的是对象中键名为 0 的属性的键值。这很重要,因为当你把数组作为对象看待,再结合高阶函数的运行原理,上面的问题就很好理解了。

当你使用 Array 构造函数创建了一个新的数组时,实际上是创建了一个新的数组对象,它的 length 属性等于你传给 Array 的参数,除此以外,这个对象是一个空对象。对象中并没有数组对应的索引键(index key)。

{
  //no index keys!
  length: 100
}

当你试图访问索引值为 0 的数组成员时,访问结果是 undefined,但这不是因为在索引键为 0 的位置存储的值是 undefined,而是因为 JavaScript 规定,当访问一个对象中并不存在的键名对应的键值时,会返回 undefined

当 mapreducefilterforEach 等高阶函数沿着 0 到数组长度的索引键遍历数组对象时,就会发生上面的现象,但是只有当对象的键值存在时,回应的回调函数才会执行。所以,当我们使用 map 对数组遍历时没有执行回调函数–就是因为索引键并不存在。


如何解决?

const arr = [...Array(100)].map(x =>x);

WX20210316-135109@2x.png

将数组展开到一个空数组后会生成一个新数组,它每个成员都是 undefined我们就得到了一个新的数组,数组成员都具备了索引键,因此是可以使用 map 进行遍历的了(同样也可以使用 reducefilterforEach 进行遍历)

{
  0: undefined,
  1: undefined,
  2: undefined,
  ...
  99: undefined,
  length: 100
}


Array(100),map(),reduce(),filter(),forEach(),new Array(100)

手机扫码访问