在撰写本文时 MDN 对
Array.from
函数的描述 指出:
有一个可选参数 mapFn,它允许您对正在创建的数组的每个元素执行 map() 函数。Array.from()
更清楚,
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 规范:调用(
mapfn,thisArg,«nextValue,k»)。
而对于
规范有:Call(
callbackfn*, thisArg, « kValue, k, O »).
显然,上面引用的 MDN 并不完全正确。
问题
Array.from
像
map()函数那样工作不是更有意义吗?
在发布此问题一段时间后,Mozilla 贡献者在上面引用的段落中添加了一个条款:
...,并且resultmapFn
仅接收两个参数 (
,element
),而没有整个数组,因为数组仍在构建中。 但是这个“因为”似乎混淆了原始数据和映射结果。正在构造的数组是index
数组,而 Array#map
回调采用的第三个参数是
source对象。另外,结果数组仍在构建中......在我看来,这是一个转移注意力的事情。很可能将作为第一个参数传递给
Array.from
的源 object 作为第三个参数传递。完全正确。但这也是不完整的。 几乎不正确:
它允许您
执行执行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()
将其转换为物化视图。这是先有鸡还是先有蛋的问题。