当我们随便给出一个数组,大家都能想到很多数组的方法:pop、push、forEach、find、findIndex、map…(具体方法可以查看>>传送门<<)
然而这些方法的使用,真的像你心目中所想得那么“熟练”吗?让我们一起看下下面的例子:
这个结果是什么?
A同学:当然是[3]了!——那么这类同学,赶紧去回顾下数组的基本使用方法,暂时先别往下看了。
B同学:当然是[undefined,undefined,undefined]了!——那么,这类同学请往下看吧!
C同学:当然是[,,]了,——那么,恭喜你,跟着B同学继续往下看吧!
D同学:当然是[empty × 2],——那么,请跟着C同学继续往下看吧!(注意:[empty × 2]其实就是[,,],在真正打印[empty × 2]是报错的,应该写成[,,],而这个[,,]其实就是[undefined,undefined,undefined],但这个undefined跟下文的undefined仍然有些不同,请继续往下看)
既然,我们得到了一个长度为3的空数组,那么我们再来看下下面这个例子:
let arr = new Array(3);let newArr = arr.map(function(item,index,origin){ return 'zhuangzhuang';})console.log(newArr);请问这回打印的结果是什么?
很多人都会觉得是[‘zhuangzhuang’,’zhuangzhuang’,’zhuangzhuang’];
那么,恭喜这些同学,你们可以往下看了,真相就在下面…
其实,愤怒的毛衣在控制台打印的时候,你会惊奇地发现答案竟然是:
What???
其实,这个空元素,就是我们new Array(3)产生的空元素。
[,,]中的空元素,是否是undefined?
console.log([,,][0] === undefined );//true可见,[,,]就是[undefined,undefined,undefined](在这里不比较地址)
再看看[undefined,undefined,undefined]既然[,,]就是[undefined,undefined,undefined],那么,我们让[undefined,undefined,undefined]尝试使用map方法,如下:
let arr = [undefined,undefined,undefined];let newArr = arr.map(function(item,index,origin){ return 'zhuangzhuang';})console.log(newArr);答案如下:
What???
明明[,,]就是[undefined,undefined,undefined],为何前者使用map是[,,],后者是[“zhuangzhuang”, “zhuangzhuang”, “zhuangzhuang”]
很多人看到这里已经晕了,别急,继续往下看!
为了弄清楚这种神奇的现象,我们不得不找出MDN大神级文档,看看文档是怎么说吗的:
map 方法会给原数组中的每个元素都按顺序调用一次 callback 函数。callback 每次执行后的返回值(包括 undefined)组合起来形成一个新数组。 callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。
可见,其实new Array(3)产生的数组,每个元素都是未赋值的,并非是undefined值,只不过在做===比较的时候,会让未赋值的与undefined相等。
所以,我们只需要明白:针对未赋值的元素或使用delete删除的元素,使用map方法时,是不会被调用的,仅仅只有那些赋值过的值才会调用map的callback。
结果为:
同样的,如果用delete删除,如下:
如果在使用map方法过程中,想避免这类尴尬发生,那么其实解决办法也很简单——-让元素赋值
元素赋值一般常用的是arr.fill()方法等。这块内容在这就不做详细介绍了。具体可以参看MDN关于数组方法的讲解(点击>>传送门<<)!