求star

开源不易,喜欢请点个star吧

Ocean Han
686 字
3 分钟
JS中使用Array.apply()初始化数组
2022-07-24

遇到问题#

WARNING

​ 今天在使用Array构造函数初始化数组的时候遇到问题,代码如下:

  Array(10).forEach(function(){
    // do something ... ...
  })

​ 这样写的结果是,并不会进入forEach的遍历

TIP

​ 经过查询mdn之后发现:

  • forEach方法按升序,为数组中含有有效值的每一项执行一次callback函数,哪些已经删除(使用delete方法等)或者未初始化的项,将会被跳过(但不包括值为undefined的项)(例如在稀疏数组上)

通过Array(10)或者 new Array(10)方式创建的数组是一个有length属性的空数组,其中每个元素还没有被赋值(未初始化),所以会被forEach等方法跳过

解决问题:key:#

TIP

​ 今天在学习的过程中,遇到需要快速生成一个数组的需求,看到了别人利用apply方法,发现能解决这个问题。代码如下:

let list = ref(Array.apply(null, { length: 81 } as number[]).map((_, index) => {
    // do something ... ...
}))
// 这三个方法返回的是一个长度为10的数组,且每一个元素都被赋值成undefined

Array.apply(null, {length: 10}) 
Array.apply(null, Array(10)) 
Array.apply(null, new Array(10)) 

// [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]
TIP

​ 下面是mdn关于Array的引用:

  • Array 构造器会根据给定的元素创建一个 JavaScript 数组, 但是当仅有一个参数且为数字时除外: 一个范围在 0 到 232-1 之间的整数, 此时将返回一个length 的值等于 arrayLength 的数组对象(言外之意就是该数组此时并没有包含任何实际的元素, 不能理所当然地认为它包含 arrayLength个值为 undefined 的元素)。 注意,后面这种情况仅适用于用 Array 构造器创建数组,而不适用于用方括号创建的数组字面量。
TIP

然后是apply方法:

  • 第一个参数: 调用时指定的上下文(context)
  • 第二个参数: 一个数组或一个类数组对象

由于 我们在第二个参数传入了一个具有length属性的对象,所以它将会被看作 类数组对象

​ :arrow_down:

所以,相当于给 Array()传入了一个length为10 的空数组

​ :arrow_down:

于是,把空数组中每项的值逐个传入Array,而这些值都是undefined

  // 伪代码
  var arrayLike = {length: 2}
          ↓↓
  Array.apply(null, arrayLike)
          ↓↓
  Array(arrayLike[0], arrayLike[1]) // 把一个空数组中的每一个元素的值逐个传入Array()方法
          ↓↓
  Array(undefined, undefined) // 而空数组中的每一个元素的值都为undefined

另外es6提供了Array.from()可以做到相同的结果

  Array.from({length: 5})
  // [undefined, undefined, undefined, undefined, undefined]

利用扩展运算符的另外一种写法:

  Array(...Array(5))
  // 或
  [...Array(10)]
  // [undefined, undefined, undefined, undefined, undefined]
JS中使用Array.apply()初始化数组
https://blog.oceanh.top/posts/frontend/使用arrayapply初始化数组/
作者
Ocean Han
发布于
2022-07-24
许可协议
CC BY-NC-SA 4.0
最后修改时间
2024-08-10 10:08:49