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

问题描述 投票:0回答:2
ES6 中添加的

JavaScript 的 class 语法,显然使得 extend

null
变得合法:

class foo extends null {}

new foo();

一些谷歌搜索显示,在 ES Discuss 上建议这样的声明是错误的;然而,其他评论者认为它们应该保持合法,因为

有人可能想创建一个具有

{__proto__: null}
原型的类

这一方的论点最终占了上风。

我无法理解这个假设的用例。一方面,虽然这样一个类的“声明”是合法的,但以这种方式声明的“实例化”类似乎是不合法的。尝试在 Node.js 或 Chrome 中实例化上面的类 foo 给了我一个非常愚蠢的错误

类型错误:函数不是函数

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

类型错误:函数(){

} 不是构造函数

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

class bar extends null { constructor() {} } new bar();


然后 Chrome/Node 告诉我:

ReferenceError:未定义

Firefox 告诉我:

参考错误:|这个|在 bar 类构造函数中使用未初始化

这一切到底是怎么回事?为什么这些空扩展类不可实例化?鉴于它们不可实例化,为什么在规范中故意留下了创建它们的可能性,以及为什么一些 MDN 作者认为它“值得记录”?此功能有哪些可能的用例?

编辑(2021):TC39,它指定了 JavaScript 仍然没有准确地解决它应该如何工作。这需要在浏览器能够一致地实现它之前发生。您可以关注

这里
javascript ecmascript-6 es6-class
2个回答
30
投票

原答案

实例化这样的类是为了工作; Chrome 和 Firefox 只是存在错误。
这里

Chrome,这里 Firefox。它在 Safari 中运行良好(至少在 master 上)。

规范中曾经有一个bug,导致它们无法实例化,但它已经修复了一段时间。 (还有一个相关的,但那不是你看到的。) 用例与

Object.create(null)

大致相同。有时您想要的东西不是从 Object.prototype 继承的。

回答

第二
部分:

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

14
投票

这样,你的对象的原型链中就不会有 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 这样的大型代码库。

    
实际上可以构造一个扩展 null 的类,这样

class bar extends null{ constructor(){ super() //required } } //super is not a function //change the super class (for static methods only) Object.setPrototypeOf(bar, class{}) let instance = new bar() //instances still have null prototype console.log(instance.toString) //undefined

    

© www.soinside.com 2019 - 2024. All rights reserved.