【神奇】为什么这类Javascript的数组不能随便使用map方法?

当我们随便给出一个数组,大家都能想到很多数组的方法:pop、push、forEach、find、findIndex、map…(具体方法可以查看>>传送门<<)
然而这些方法的使用,真的像你心目中所想得那么“熟练”吗?让我们一起看下下面的例子:

let arr = new Array(3);
console.log(arr);

这个结果是什么?
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’];
那么,恭喜这些同学,你们可以往下看了,真相就在下面…
其实,当你在控制台打印的时候,你会惊奇地发现答案竟然是:
【神奇】为什么这类Javascript的数组不能随便使用map方法?_第1张图片
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);

答案如下:
【神奇】为什么这类Javascript的数组不能随便使用map方法?_第2张图片
What???
明明[,,]就是[undefined,undefined,undefined],为何前者使用map是[,,],后者是[“zhuangzhuang”, “zhuangzhuang”, “zhuangzhuang”]
很多人看到这里已经晕了,别急,继续往下看!

真相只有一个

为了弄清楚这种神奇的现象,我们不得不找出MDN大神级文档,看看文档是怎么说吗的:
【神奇】为什么这类Javascript的数组不能随便使用map方法?_第3张图片
map 方法会给原数组中的每个元素都按顺序调用一次 callback 函数。callback 每次执行后的返回值(包括 undefined)组合起来形成一个新数组。 callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。


可见,其实new Array(3)产生的数组,每个元素都是未赋值的,并非是undefined值,只不过在做===比较的时候,会让未赋值的与undefined相等。
所以,我们只需要明白:针对未赋值的元素或使用delete删除的元素,使用map方法时,是不会被调用的,仅仅只有那些赋值过的值才会调用map的callback。

let arr = new Array(3);
arr.push('zhuangzhuang');//[empty*3,'zhuangzhuang']
let newArr = arr.map(function(item,index,origin){
    return item = {
        name:item
    }
})
console.log(newArr);

结果为:
【神奇】为什么这类Javascript的数组不能随便使用map方法?_第4张图片
同样的,如果用delete删除,如下:
【神奇】为什么这类Javascript的数组不能随便使用map方法?_第5张图片

解决办法

如果在使用map方法过程中,想避免这类尴尬发生,那么其实解决办法也很简单——-让元素赋值
元素赋值一般常用的是arr.fill()方法等。这块内容在这就不做详细介绍了。具体可以参看MDN关于数组方法的讲解(点击>>传送门<<)!

你可能感兴趣的:(前端,趣文,es6,map,undefined,array,数组)