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

时间:2016-12-16 17:06:24

标签: javascript ecmascript-6 es6-class

在ES6中添加的JavaScript class syntax显然使其extend null合法:

class foo extends null {}

一些谷歌搜索显示,was suggested on ES Discuss这样的声明是错误的;然而,其他评论者认为他们在合理的基础上是合法的

  

有人可能想要创建一个具有{__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

这种疯狂是什么?为什么这些空扩展类不可实例化?鉴于它们不是可实例化的,为什么故意创建它们的可能性留在规范中,为什么一些MDN作者认为它是noteworthy enough to document?这个功能有哪些可能的用例?

2 个答案:

答案 0 :(得分:23)

实例化这样的类是有意义的; Chrome和Firefox只是有bug。 Here's Chrome,here's Firefox。它在Safari中工作正常(至少在master上)。

规范中曾经有一个bug,这使得它们无法实例化,但它已经修复了一段时间。 (still是一个相关的,但那不是你所看到的。)

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

答案 1 :(得分:10)

回答第二个部分:

  

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

这样,您的对象在其原型链中就不会有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

我们知道,undefined实际上不是一个函数。在这种情况下,我们可以创建对象,而不必担心不应该在那里的字段上进行调用。

这是Object.create(null)的常见模式,在许多代码库中都很常见,包括像NodeJS这样的大代码。