gpt4 book ai didi

javascript - 为什么 Map 在 chrome/node 中不能子类化?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:03:59 25 4
gpt4 key购买 nike

所以 ES 6 给我们带来了 Maps (而且不会很快)。为了我自己的邪恶目的,我希望将 Map 子类化,我尝试了以下方法(为清楚起见缩写):

function Foo() {
return Map.apply(this, [].slice.call(arguments));
}

var bar = new Foo();

在 V8 环境中,这会抛出一个错误“Map constructor not called with 'new'”。为什么? SpiderMonkey 得到了这个“正确的”:

Map.call({}, [['foo', 'bar']]).get('foo');

将如预期的那样产生“bar”。在 SpiderMonkey 和 V8 中尝试类似的东西

function Foo() {};
Foo.prototype = new Map();
var bar = new Foo();
bar.set('foo', 'bar');

将失败:“在不兼容的对象上调用的方法集”。所以就有了继承模式。据我所知 spec (我没有太多的 spec-foo),实际的 Map 对象具有无法访问的内部属性,这些属性是它们正常​​工作所必需的。但为什么 V8 会在第一个模式上抛出错误?这似乎是一个奇怪的决定,尤其是当它在 FF 中按预期工作时。

更新:我注意到 FF 和 chrome 都实现了 Object.setPrototypeOf。以防万一有人偶然发现这个并想到那个,我可以告诉你它失败了。以下两种情况因不同原因而失败:

//this totally fails, even for custom constructors/objects
var Foo = function(){};
Object.setPrototypeOf(Foo, Map.prototype);
var bar = new Foo(); //bar doesn't have any of the Map properties/methods

//this one has the methods but still throws the 'incompatible object'
//err. Also fails with new Map() instead of Map.prototype
var bar = Object.setPrototypeOf({}, Map.prototype);

长话短说

基本上有四种扩展 map 的方法(一些来自下面的答案/评论):

  1. 向 Map.prototype 添加方法(真丢人)。
  2. 工厂/构造函数使用您委托(delegate)给的内部 Map 实例生成对象
  3. 将属性复制到 map 上的 Mixin fn:
function Foo(){this.bar = 'boo!'}
var baz = new Map();
Foo.call(baz);
baz.bar; //yields 'boo!'
baz.set('5', 5).get('5'); //yields 5

或者只是等待 ES 6 类进入您关心的平台

最佳答案

In V8 environments this throws an Error "Map constructor not called with 'new'". Why?

因为新的 ES6 类(包括内置类)应该只能用 new 构造。

SpiderMonkey gets this 'right'

不完全是。 The spec明确地说

Map is not intended to be called as a function and will throw an exception when called in that manner.

Wishing to subclass Map

是的,这是合适的:

The Map constructor is designed to be subclassable. It may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Map behaviour must include a super call to the Map constructor to create and initialize the subclass instance with the internal state necessary to support the Map.prototype built-in methods.

所以你会想要使用

class Foo extends Map {
// default constructor
}
var bar = new Foo();
bar.set('foo', 'bar');

关于javascript - 为什么 Map 在 chrome/node 中不能子类化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28900954/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com