繁体   English   中英

`map()`的奇怪行为

[英]Weird behavior of `map()`

AS:为简单起见,更改了变量名称。

我的目标是创建一个类似于数组的新类,每个实例都有七个数字,基于任何参数的数量。

所以,代码是这样的:

"use strict";
class SevenNumbers extends Array {
    constructor(...args) { debugger; // !
        // Cut the rest; fill the gaps; convert: first to object, then to primitive
        super(...Object.assign([0, 0, 0, 0, 0, 0, 0], args.slice(0, 7)).map(arg => +new Number(arg)));
    }
}

它工作正常,所以new SevenNumbers(); 返回七个数字的数组,默认(0)或不是。
debugger -part很重要:它告诉我们如何进入SevenNumbers类的构造函数。

当我尝试map()对象时出现问题。
请尝试以下代码:

var arr = new SevenNumbers(8, 7, 6, 5, 4, 3, 2, 1);
// SevenNumbers [8, 7, 6, 5, 4, 3, 2] (without the last).
arr.map(_ => _);
// Array [8, 7, 6, 5, 4, 3, 2].

第一部分以预测的方式工作,但在第3行我们再次进入构造函数!
最令人困惑的是,这里唯一的论点是arr的长度。 为什么长度?

尽管最终结果是正确的,但这种奇怪的行为会干扰我在实践中的工作,因为它们之间还有其他的计算方法。

这有什么不对? 为什么不从现成的自定义数组中获取值,为什么要创建新的?

那是因为map使用ArraySpeciesCreate来创建一个类似于原始数组的数组。

如果没有发生这种情况,最后你会获得一个普通的Array而不是SevenNumbers实例。

因此,调用构造函数以构造将使用回调函数和原始实例的项填充的新数组。

如果您不想要它,可以使用Symbol.species来制作map调用Array而不是SevenNumbers

 class SevenNumbers extends Array { constructor(...args) { console.log(args.toString()); super(...Object.assign([0, 0, 0, 0, 0, 0, 0], args.slice(0, 7)).map(arg => +new Number(arg))); } static get [Symbol.species]() { return Array; } } new SevenNumbers(8, 7, 6, 5, 4, 3, 2, 1).map(_ => _); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM