我如何以及为什么要编写扩展 null 的 class?
How and why would I write a class that extends null?
JavaScript的class syntax, added in ES6, apparently makes it legal to extend null
:
class foo extends null {}
一些谷歌搜索显示 was suggested on ES Discuss 这样的声明是错误的;然而,其他评论者认为他们应该合法,因为
someone might want to create a class that has a {__proto__: null}
prototype
最终争论的一方占了上风。
我无法理解这个假设的用例。一方面,虽然 declaration 这样的 class 是合法的,但似乎 instantiating a class declared in这条路不是。尝试在 Node.js 或 Chrome 中从上面实例化 class foo
给我一个非常愚蠢的错误
TypeError: function is not a function
在 Firefox 中做同样的事情给了我
TypeError: function () {
} is not a constructor
在 class 上定义构造函数没有帮助,如 MDN 的当前功能示例所示;如果我尝试实例化这个 class:
class bar extends null {
constructor(){}
}
然后Chrome/Node告诉我:
ReferenceError: this is not defined
Firefox 告诉我:
ReferenceError: |this| used uninitialized in bar class constructor
这是什么疯狂行为?为什么这些空扩展 classes 不可实例化?鉴于它们不可实例化,为什么在规范中故意保留创建它们的可能性,为什么一些 MDN 作者认为它是 noteworthy enough to document?此功能有哪些可能的用例?
EDIT (2021):TC39,它指定 JavaScript 仍然没有解决它应该如何工作。这需要在浏览器可以一致地实现它之前发生。你可以关注最新的努力here.
原回答:
实例化这样的 类 是为了工作; Chrome 和 Firefox 只是有错误。 Here's Chrome's, here's 火狐的。它在 Safari 中运行良好(至少在 master 上)。
曾经有一个 bug in the spec which made them impossible to instantiate, but it's been fixed for a while. (There's still 相关的,但你现在看到的不是这个。)
用例与Object.create(null)
大致相同。有时你想要一些不继承自 Object.prototype
.
的东西
回答第二部分:
I can't make much sense of this hypothetical use case.
这样,您的对象的原型链中将不会有 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 这样的大型代码库。
JavaScript的class syntax, added in ES6, apparently makes it legal to extend null
:
class foo extends null {}
一些谷歌搜索显示 was suggested on ES Discuss 这样的声明是错误的;然而,其他评论者认为他们应该合法,因为
someone might want to create a class that has a
{__proto__: null}
prototype
最终争论的一方占了上风。
我无法理解这个假设的用例。一方面,虽然 declaration 这样的 class 是合法的,但似乎 instantiating a class declared in这条路不是。尝试在 Node.js 或 Chrome 中从上面实例化 class foo
给我一个非常愚蠢的错误
TypeError: function is not a function
在 Firefox 中做同样的事情给了我
TypeError: function () {
} is not a constructor
在 class 上定义构造函数没有帮助,如 MDN 的当前功能示例所示;如果我尝试实例化这个 class:
class bar extends null {
constructor(){}
}
然后Chrome/Node告诉我:
ReferenceError: this is not defined
Firefox 告诉我:
ReferenceError: |this| used uninitialized in bar class constructor
这是什么疯狂行为?为什么这些空扩展 classes 不可实例化?鉴于它们不可实例化,为什么在规范中故意保留创建它们的可能性,为什么一些 MDN 作者认为它是 noteworthy enough to document?此功能有哪些可能的用例?
EDIT (2021):TC39,它指定 JavaScript 仍然没有解决它应该如何工作。这需要在浏览器可以一致地实现它之前发生。你可以关注最新的努力here.
原回答:
实例化这样的 类 是为了工作; Chrome 和 Firefox 只是有错误。 Here's Chrome's, here's 火狐的。它在 Safari 中运行良好(至少在 master 上)。
曾经有一个 bug in the spec which made them impossible to instantiate, but it's been fixed for a while. (There's still 相关的,但你现在看到的不是这个。)
用例与Object.create(null)
大致相同。有时你想要一些不继承自 Object.prototype
.
回答第二部分:
I can't make much sense of this hypothetical use case.
这样,您的对象的原型链中将不会有 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 这样的大型代码库。