如何以及为什么我会写一个扩展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.prototype
inheritance。
回答第二部分:
我无法理解这个假设的用例。
这样,你的对象的原型链中就不会有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)
很常见。