为什么Array.from不以与Array.Prototype.map相同的方式调用回调?
撰写时MDN's description of the Array.from
function状态:
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
不向回调传递第三个参数。
这与Array.from
上的ECMAScript 2020规范一致:
Call(mapfn,thisArg,«nextValue,k»)。
而对于Array.prototype.map
,规范具有:
Call(callbackfn,thisArg,«kValue,k,O»)。
显然,以上引用自MDN并不完全正确。
问题
为什么会有这样的差异?让Array.from
像上面引用的MDN中所述的map()函数那样工作不是更有意义吗?
mdn
mdn中的引用几乎完全正确。
解决方案
mdn引用几乎完全正确。但它也是不完整的。
几乎不正确:
它允许您执行map()函数
它不会执行本机.map()
方法。它执行的映射操作几乎与相同。
未完成
更清楚,
Array.from(obj, mapFn, thisArg)
结果与Array.from(obj).map(mapFn, thisArg)
、
相同 只是它不创建中间数组。
在为True时,只要未使用.map()
的第三个参数,也应包括";。";以绝对100%匹配事物的工作方式。
为什么会有这样的差异?让
Array.from
像上面引用的MDN中所述的map()函数那样工作不是更有意义吗?
问题很有趣,但答案实际上很无聊。因为您可以在非数组上使用Array.from()
。
这有什么关系?您显示了一个类似数组的映射。类似数组的整体存在于中,可以作为第三个参数进行传递。实际上是通过.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()
将其转换为物化视图。这是一个先有鸡还是先有蛋的问题。
相关文章