为什么Array.from没有像Array.prototype.map一样调用回调?

问题描述 投票:0回答:1

在撰写本文时 MDN 对

Array.from
函数的描述 指出:

Array.from()
有一个可选参数 mapFn,它允许您对正在创建的数组的每个元素执行 map() 函数。

更清楚,

Array.from(obj, mapFn, thisArg)

Array.from(obj).map(mapFn, thisArg)
,
具有相同的结果 只是它不创建中间数组。

但是,它没有“完全相同”的行为,如下所示:

function mapFn(...args) { console.log(...args); } let obj = { 0: "value", length: 1 }; let thisArg = { }; Array.from(obj, mapFn, thisArg); Array.from(obj).map(mapFn, thisArg);

Array.from

不会将第三个参数传递给回调。

这符合 ECMAScript 2020 规范 

Array.from

:

调用(
mapfn

thisArg,«nextValuek»)。

而对于

Array.prototype.map

 规范有:

Call(
callbackfn

, thisArg, « kValue, k, O »).

显然,上面引用的 MDN 并不完全正确。
*

问题

为什么会出现这种差异?正如上面引用的 MDN 中所述,让

Array.from

map()
函数那样工作不是更有意义吗?


*

在发布此问题一段时间后,Mozilla 贡献者在上面引用的段落中添加了一个条款:

...,并且
mapFn

仅接收两个参数 (

element
,
index
),而没有整个数组,因为数组仍在构建中。

但是这个“因为”似乎混淆了原始数据和映射结果。正在构造的数组是
result

数组,而 Array#map 回调采用的第三个参数是

source
对象。另外,结果数组仍在构建中......在我看来,这是一个转移注意力的事情。很可能将作为第一个参数传递给 Array.from 的源 object 作为第三个参数传递。
    

javascript ecmascript-6 callback mapping
1个回答
1
投票
几乎

完全正确。但这也是不完整的。 几乎不正确:

它允许您
执行

map()函数

它不会
执行

本机.map()方法。它执行“几乎”相同的映射操作。

不完整

更清楚,

Array.from(obj, mapFn, thisArg)

Array.from(obj).map(mapFn, thisArg)

,
具有相同的结果 只是它不创建中间数组。
虽然 true 还应该包括“
只要不使用

.map()
的第三个参数。

”以绝对 100% 匹配事物的工作方式。

为什么会出现这种差异?正如上面引用的 MDN 中所述,让 Array.from

map()

函数那样工作不是更有意义吗?


有趣的问题,但答案实际上很无聊。这是因为您可以在非数组上使用 Array.from()

为什么这很重要?你展示了一个类似数组的映射。类似数组的

exists
是完整的,它可以作为第三个参数传递。事实上

它是

通过实施.map()


function mapFn(...args) { console.log(this, ...args); // ^^^^^ also log this for clarity } let obj = { 0: "value", length: 1 }; let thisArg = { this: "arg" }; Array.prototype.map.call(obj, mapFn, thisArg);


但是,情况并非如此,如果整个值
不存在

,就像您使用迭代器一样:

function* example() { yield 1; yield 2; yield 3; if (Math.random() < 0.5) //make the iterator result uncertain yield 4; } function mapFn(...args) { console.log(...args); } Array.from(example(), mapFn)


每次调用映射回调时,它只知道
当前

现有值。迭代器还没有物化,所以你不仅无法看到它的完整视图,而且是

Array.from()

将其转换为物化视图。这是先有鸡还是先有蛋的问题。


© www.soinside.com 2019 - 2024. All rights reserved.