如何以及为什么我会写一个扩展null的类?

在ES6中添加了JavaScript的类语法 ,显然使得扩展为null是合法的:

 class foo extends null {} 

一些谷歌search显示, 在ES的讨论中提出这样的声明是错误的; 然而,其他评论者认为他们在这个基础上是合法的

有人可能想要创build一个具有{__proto__: null}原型的类

争论的这一面最终占了上风。

我无法理解这个假设的用例。 首先,虽然这样一个类的声明是合法的,但是实例化一个这样声明的类却不是。 尝试在Node.js或Chrome上从上面实例化类foo给了我非常愚蠢的错误

 TypeError: function is not a function 

而在Firefox做同样的事情给了我

 TypeError: function () { } is not a constructor 

在MDN当前的特性示例中显示,在类上定义构造函数并没有帮助。 如果我尝试实例化这个类:

 class bar extends null { constructor(){} } 

那么Chrome / Node告诉我:

 ReferenceError: this is not defined 

Firefox告诉我:

 ReferenceError: |this| used uninitialized in bar class constructor 

这是什么疯狂? 为什么这些空扩展类不能实例化? 而且鉴于它们不是可实例化的,为什么在规范中故意将它们创build的可能性,以及为什么一些MDN作者认为这是值得注意的文件 ? 这个function有什么可能的用例?

实例化这样的类是为了工作; Chrome和Firefox只有错误。 这里是 Chrome的, 这里是 Firefox的。 它在Safari(至less在主)上工作正常。

曾经有一个规范中的bug使得它们不可能实例化,但是它已经被固定了一段时间。 (还有一个相关的,但这不是你所看到的。)

用例与Object.create(null)大致相同。 有时候你想要的东西不会从Object.prototypeinheritance。

回答第二部分:

我无法理解这个假设的用例。

这样,你的对象的原型链中就不会有Object.prototype了。

 class Hash extends null {} var o = {}; var hash = new Hash; o["foo"] = 5; hash["foo"] = 5; // both are used as hash maps (or use `Map`). hash["toString"]; // undefined o["toString"]; // function 

我们知道,事实上它并不是一个函数。 在这种情况下,我们可以创build对象,而不用担心在不应该出现的字段上调用。

这是通过Object.create(null)的常见模式,并且在很多代码库(包括像NodeJS这样的大代码库Object.create(null)很常见。