JavaScript 作为一门动态语言,一直受到许多语言特性上的限制,尤其是数组的操作。为了解决这些限制,ES6 引入了许多新特性,比如模板字符串,解构赋值,箭头函数等。而在 ES7 中新增了一个新的静态函数——Array.from,该函数可以将类数组对象或可迭代对象转换为一个真正的数组。
Array.from 的用法
Array.from 函数接收两个参数:第一个参数 source,要转换的对象;第二个参数 mapFn,可选参数,对每个数组元素进行处理的函数。
Array.from(arrayLike[, mapFn[, thisArg]])
Array.from 的例子
类数组对象
下面是一个常见的场景,需要将类数组对象转换为数组。可以直接传递类数组对象作为第一个参数给 Array.from,即可转换为一个数组。
const arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 }; const arr = Array.from(arrayLike); // arr 为 ['a', 'b', 'c']
可迭代对象
除了类数组对象,Array.from 还可以转换可迭代对象,可迭代对象可以是一个 Set、Map、String、Array 等类型。这里以 Set 类型为例:
const set = new Set([1, 2, 3]); const arr = Array.from(set); // arr 为 [1, 2, 3]
对元素进行处理
如果想对每个数组元素进行更高级、更复杂的处理,可以将处理函数传递给第二个参数 mapFn。 这个处理函数有两个参数:value 和 index,表示值和索引。然后,Array.from 会将每个元素逐个传递给这个函数进行处理,并将处理结果存储在新生成的数组中。
例如,将 Set 中每个数字乘以 2 并存储在数组中:
const set = new Set([1, 2, 3]); const arr = Array.from(set, value => value * 2); // arr 为 [2, 4, 6]
与扩展运算符对比
那么,将一个可迭代对象转换为数组,Array.from 与 [...iterable](扩展运算符)有什么区别呢?可以看下面的例子:
const arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 }; const arr1 = Array.from(arrayLike); const arr2 = [...arrayLike]; // 报错,因为不是迭代器 const set = new Set([1, 2, 3]); const arr3 = Array.from(set); const arr4 = [...set];
扩展运算符只能用于可迭代对象,不能用于类数组对象;而 Array.from 既可以用于可迭代对象,也可以用于类数组对象。
类似数组的对象
有一些对象被称为“类似数组的对象”,它们看起来像一个数组,但是没有数组的方法(如 push、pop、slice 等)。在这些情况下,Array.from 的低效性可能会对性能产生负面影响,因为它通过一个 for 循环遍历。
可以使用 Array.from 的另一个变体,该变体同样接受一个映射函数,但是该函数放在可选参数之前,并且不接受源对象。相反,它将其索引作为第一个参数。例如,可以像这样使用 Array.from:
Array.from({ length: 5 }, (v, i) => i); // [0, 1, 2, 3, 4]
这可能看起来很奇怪,但它实际上是很高效的。它通过自己的迭代生成一个数组或类数组对象(具有“0”到“length-1”属性的对象),然后连续地映射并返回该数组。这是一个更高效的解决方案,因为它不需要通过循环进行迭代。此方法适用于将带有 for 迭代器的循环转换为用于生成数组的映射。
总结
Array.from 函数是 ES7 中新增的静态函数,用于将类数组对象或可迭代对象转换为一个真正的数组。它的基本用法非常简单,只需要将需要转换的对象作为第一个参数传递给数组即可。同时,它可以选取一个可选参数 mapFn,用于对每个数组元素进行处理。在使用时,我们需要根据具体情况选择使用 Array.from 还是扩展运算符来达到最佳效果。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64605828968c7c53b020d9f8