分析Array.apply(null, {length: 20})

vue文档中介绍渲染20个重复段落的实现方式

render: function (createElement) {
  return createElement('div',
    Array.apply(null, { length: 20 }).map(function () {
      return createElement('p', 'hi')
    })
  )
}

这段代码中有Array.apply(null, { length: 20 })这段代码,看起来挺有意思,这不就是创建20个空数组吗,为什么要这样写呢?

换成new Array(20)的方式来实现

(new Array(20)).map((v, i) => {
    console.log('index:', i);
})

运行发现控制台什么也没有输出,打印new Array(20),输出结果为[ <20 empty items> ]。同时再打印Array.apply(null, {length: 20})创建的数组,输出为[undefined,undefined,undefined....],是一个包含20个undefined的数组。

原来,使用new Array(20)方式只是初始化创建了一个长度为20的数组,但是数组中的内容并没有被初始化。

为什么包含长度为20的未初始化数组使用map却没有执行遍历呢?关于这个问题,可以参考MDN上关于map的介绍

MDN原文内容(Array.prototype.map

map 方法会给原数组中的每个元素都按顺序调用一次 callback 函数。callback 每次执行后的返回值(包括 undefined)组合起来形成一个新数组。 callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。

apply的第二个参数为一个数组,当然也可以为一个类数组。所谓类数组,即包含length属性,所以{length: 20}就是一个类数组,传递给apply,就相当于一个长度为20的数组,并且每个数组的值都被初始化为undefined,所以Array.apply(null, {length: 20})就初始化为了一个包括20个值为undefined的数组。

既然值被初始化了,那么map当然能够正常遍历了,下面的语句也就能够正常打印出0-19的信息。

Array.apply(null, {length: 20}).map((v, i) => {
    console.log('index:', i);
})

这是es5的写法,在es6还可以使用Array.from()函数转换一个类数组为真正数组,所以,Array.from({length: 20})Array.apply(null, {length: 20})是等效的。

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注