欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

理解可迭代对象和类数组对象的差异

最编程 2024-01-13 18:52:47
...

by @zhangbao(zhangbao) #0107

注意,这里所指的“对象”并非是严格意义上的对象。像字符串这样的基本类型值也叫对象。

概览

  • 可迭代对象是指实现了 [Symbol.iterator] 方法属性的对象。
  • 类数组对象则具有一个 .length 属性。
  • 可以使用 Array.from 将可迭代对象和类数组对象转为真实数组。

image.png

辨别

可迭代对象类数组对象是两个完全不同的概念,不要弄混了。

  • 可迭代对象 是指实现了 [Symbol.iterator] 方法属性的对象。
  • 类数组对象 则具有一个 .length 属性,因此说它是类似数组的。

比如,下面的类数组对象就能不用 for...of 循环遍历。

// 因为具有 length 属性,因此属于类数组对象
let arrayLike = {
  0: "Hello",
  1: "World",
  length: 2
};

// 报错!for...of 是无法遍历没有部署 [Symbol.iterator] 属性的对象的
for (let item of arrayLike) {}

但是,可迭代对象和类数组对象并非是相互排斥的。比如,字符串既是可迭代对象(能够被 for...of 循环遍历),又是类数组对象。

image.png

但不管是可迭代对象还是类数组对象,说其他它们都不是真实意义上的数组,因此不具备诸如 forEachmapfilterreduce 等这些数组方法。这有时会给我们操作对象带来很大的不便,那么我们该如何做,才能在这些对象上使用数组方法呢?

答案是可以使用 Array.from 方法。

Array.from

Array.from 这个方法神奇的地方在于,它可以将传入的可迭代对象或类数组对象,都能转换成真实的数组。

两个例子

举个例子:

image.png

看到没,arrayLike 传入 Array.from 之后,返回的是真实的数组。这样我们就能很方便的使用数组方法操作数据了。

再以《可迭代对象》一文里的 range 变量为例(如下)。

let range = {
  from: 1,
  to: 5
}

range[Symbol.iterator] = function() {
  return {
    current: this.from,
    last: this.to,
    next() {
      if (this.current <= this.last) {
        return { done: false, value: this.current++ }
      } else {
        return { done: true }
      }
    }
  }
}

我们用 Array.from 处理一下。

image.png

发现也被正常处理了。

完整语法

其实上面都是基本用户,Array.from 方法的完整语法是这样的:

Array.from(obj[, mapFn, thisArg])

除了之前使用过的第一个参数,即被处理的对象,另外两个可选参数含义是:

  • mapFn:在将每个成员添加进最终返回的数组之前,执行的映射函数。
  • thisArg:指定映射函数执行上下文 this 的值。

举个例子:

image.png

从上图可以看见,通过将 mapFn 内的 this 指向 thisArg,我们将 "apple" 转为了 "????",将 "banana" 转为了 "????",最后得到了最终返回的数组 ["????", "????"]

参考链接

  • javascript.info/iterable#ar…

(完)

推荐阅读