「前端每日一问(18)」JS 中伪数组怎么转成数组

626 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

本题难度:⭐

答:

  • 使用扩展运算符
  • 使用 Array.from
  • 使用数组的 slice 方法

什么是伪数组?

基本概念

伪数组,也叫类数组,英文名称 Array-like,顾名思义,就是像数组但不是数组,有以下特征:

  • 具有 length 属性。
  • 可通过索引访问伪数组里的元素。
  • 不能调用数组上的方法。

举个例子,函数的隐式参数 arguments 就是一个伪数组,

function add () {
  console.log('arguments :>> ', arguments)
  console.log('arguments.length :>> ', arguments.length)
  console.log('arguments[0] :>> ', arguments[0])
  arguments.push(1)
}

add(1, 2, 3)

image.png

JS 常见伪数组有哪些?

argumentsDOM 元素集合。

function add () {
  console.log('arguments :>> ', arguments)
}

add(1, 2, 3)

const DOMTags = document.getElementsByClassName('test')
console.log('DOMTags :>> ', DOMTags)
console.log('document.childNodes :>> ', document.childNodes)

image.png

伪数组的类型是什么?

调用 Object.prototype.toString 方法来看一下伪数组的类型,

function add () {
  console.log('typeof arguments :>> ', Object.prototype.toString.call(arguments))
}

add(1, 2, 3)

const DOMTags = document.getElementsByClassName('test')

console.log('typeof DOMTags', Object.prototype.toString.call(DOMTags))
console.log('typeof document.childNodes :>> ', Object.prototype.toString.call(document.childNodes))

image.png

结果显而易见,伪数组的类型是专门的引用类型,比如 Arguments 对象HTMLCollectionNodeList

伪数组转数组

扩展运算符

function add () {
  const args = [...arguments]
  args.push(1) // 可以使用数组上的方法了
}

add(1, 2, 3)

Array.from

function add () {
  const args = Array.from(arguments)
  args.push(1) // 可以使用数组上的方法了
}

add(1, 2, 3)

数组 slice 方法

这个方法现在不常用了,但 es6 之前没有扩展运算符和 Array.from,用的就是这个方法。

function add () {
  const args = Array.prototype.slice.call(arguments)
  // 也可以这么写 const args = [].slice.call(arguments) 
  args.push(1) // 可以使用数组上的方法了
}

add(1, 2, 3)

为什么要调用 call

call 是函数的方法,用来改变 this 指向,用 apply 也可以。

如果不改变this指向为目标伪数组,this将永远指向调用的Array.prototype,就不会生效。

slice 方法原理

循环伪数组,把伪数组的元素挨个放到定义的一个新数组里,再返回新数组,差不多是类似这样的代码:

Array.prototype.slice = function (start, end) {
  const res = []
  start = start || 0
  end = end || this.length
  for (let i = start; i < end; i++) {
    res.push(this[i]) // 这里的 this 就是伪数组,所以要调用 call
  }
  return res
}

结尾

如果我的文章对你有帮助,你的👍就是对我的最大支持^_^

我是阿林,输出洞见技术,再会!

上一篇:

「前端每日一问(17)」手写一个深拷贝

下一篇:

「前端每日一问(19)」JS 中函数为什么被称为一等公民?