js学习-Array.apply(null, {length:100})详解

1,769 阅读2分钟

前言

不知道你有没有看见过这样一段代码,

// 如何不使用循环创建一个长度为100的数组的Object.keys()方法
var arr = Object.keys(Array.apply(null, {length:100})).map(function(item){
    return +item;
});
console.log(arr);

提示:+号是一个string转换number格式的小技巧,你也可以使用parseInt。

// 或者在vue.js教程中也出现过这样一个DOM
render: function (createElement) {
  return createElement('div',
    Array.apply(null, { length: 20 }).map(function () {
      return createElement('p', 'hi')
    })
  )
}

这两个例子的都出现过Array.apply(null, {length:100})这段代码,咋一看这是个啥?为什么Array创建数组可以这样?{length:100}是什么鬼?别着急等我慢慢讲来。

解析第一步

  • 其实直接调用Array和new Array()两种方式创建数组是一样的,即:
var a = [1,2];
var b = Array(2); 
var c = new Array(2);
console.log(a); //[ 1, 2 ]
console.log(b); //[ <2 empty items> ]
console.log(c); //[ <2 empty items> ]

注意此处输出的是[ <2 empty items> ],是因为b,c数组虽然被创建,但是该数组的元素并没有被初始化

console.log(b[0]); // undefined 
console.log(c[0]); // undefined

因为数组下标0还未初始化,访问不存在的属性返回undefined

解析第二步

apply(),的第二个参数不光可以是数组还可以是个类数组对象(即包含length属性,且length属性值是个数字的对象),所有其实{length:2}也是一个类数组对象,只是没有进行初始化而已,取值的话返回undefined

Array.apply({length:2})===Array.apply([undefined, undefined])

解析第三步

map()函数并不会遍历数组中没有初始化或者被delete的元素(有相同限制还有forEach, reduce方法),so这里也差不多解释了为什么不直接new Array(2)Array(2),而是要这样创建一个长度为2的空数组Array.apply({length:2})

// 被初始化的数组
Array.apply(null, {length: 2}).map(function(val, index){
   console.log(index); // 0 1
});
// 未被初始化的数组
Array(2).map(function(val, index){
   console.log(index); // 不会被执行
});

总结

再次之前你需要了解三个知识点

1.Arraynew Array()创建数组是没有被初始化的。

2.apply()的第二个参数可以是个类数组对象。

3.map()函数并不会遍历数组中没有初始化的元素。

拓展

如果你还是觉得Array.apply(null, {length:100})有点长的话,看过来。

// 方法1:Array(20)代替{length: 20}
Array.apply(null, Array(20)); 
   
// 方法2:使用ES6,from()函数
Array.from({length: 20})

// 方法3: 使用ES6,fill()函数
Array(20).fill(undefined)