黄qiong

1 个月前

那些年,map的坑

本文作者:IMWeb 黄qiong 原文出处:IMWeb社区 未经同意,禁止转载

前言

写需求的时候发现一个点,我想创建一个根据传入的length来生成length个0的数组。 于是,我写下了下面的代码

const result = new Array(10).map(item => 0);

然而,在浏览器中console.log一下结果,你会发现返回竟然是(10) [empty × 10],什么玩意儿,难道使用的姿势不对了么?!

原因

new Array(3)

这种写法实际上生成了[,,,]的数组。

为什么用不了map

查一下 MDC,会发现下面一段话:

map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. 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 (that is, indexes that have never been set, which have been deleted or which have never been assigned a value).

大致意思就是说,map的callback会被每一个元素调用,但是前提是这个array里的元素是有被赋值的,包括undefined,但是当数组的元素没有被赋值过,是不会被调用的。

所以当我们用new Array(3)生成这种数组[...],里面的元素都没有被赋值过,所以是callback根本不会调用。

解决方案

1.fill

既然根本原因是因为数组的元素没有被赋值过,那我就先给它赋值一波啊:

new Array(10).fill(undefined).map((val) => 0)

这样做之后妥妥生成想要的数组。

2.Function.protoType.apply

上面的方法太麻烦了,不适合我们这种想要偷懒的人,借用一下function.protoType.apply(),它会自动将没有赋值的元素看成undefined。 也就是说,下面两种写法是相等的:

Array(undefined, undefined, undefined)
Array.apply(null, Array(3))

so ~

Array.apply(null, Array(3)).map((val) => 0)

也是可以的~

3.使用ES6

[...Array(3)].map((val) => 0)

原理同上~

参考:

1.http://2ality.com/2013/11/initializing-arrays.html

2.https://stackoverflow.com/questions/5501581/javascript-new-arrayn-and-array-prototype-map-weirdness

2条评论

    您需要 注册 一个IMWeb账号或者 才能进行评论。