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

Mar*_*ery 57 javascript ecmascript-6 es6-class

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

class foo extends null {}
Run Code Online (Sandbox Code Playgroud)

一些谷歌搜索显示在ES讨论建议这样的声明是错误的; 然而,其他评论者认为他们在此基础上是合法的

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

争论的那一方最终占了上风.

我无法理解这个假设的用例.首先,虽然这样一个类的声明是合法的,但似乎实例化以这种方式声明的类不是.试图foo在Node.js或Chrome中从上面实例化类给我一个奇妙的愚蠢错误

TypeError: function is not a function
Run Code Online (Sandbox Code Playgroud)

虽然在Firefox中做同样的事情给了我

TypeError: function () {
} is not a constructor
Run Code Online (Sandbox Code Playgroud)

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

class bar extends null {
  constructor(){}
}
Run Code Online (Sandbox Code Playgroud)

然后Chrome/Node告诉我:

ReferenceError: this is not defined
Run Code Online (Sandbox Code Playgroud)

和Firefox告诉我:

ReferenceError: |this| used uninitialized in bar class constructor
Run Code Online (Sandbox Code Playgroud)

所有这些疯狂是什么?为什么这些空扩展类不可实例化?鉴于它们不是可实例化的,为什么在规范中故意创建它们的可能性,为什么一些MDN作者认为它值得注意到足以记录?这个功能有哪些可能的用例?

Bak*_*kot 23

实例化这些类是有意义的; Chrome和Firefox只是有bug.这是 Chrome的,这是 Firefox的.它在Safari中工作正常(至少在master上).

曾经有一个规范中的错误使它们无法实例化,但它已经修复了一段时间.(有还是相关的一个,但是这并不是你所看到的.)

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

  • 看起来关于`extends null`的规范已经[更改](https://github.com/tc39/ecma262/commit/c57ef95c45a371f9c9485bb1c3881dbdc04524a2),并且[Chrome没有修复这个错误](https:// bugs.chromium.org/p/v8/issues/detail?id=5115#c11)。 (2认同)

Ben*_*aum 11

回答第二部分:

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

这样,您的对象将不会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
Run Code Online (Sandbox Code Playgroud)

我们知道,undefined实际上并不是一种功能.在这种情况下,我们可以创建对象,而不必担心对不应该存在的字段进行调用.

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