为什么 ES6 类没有被提升?

新手上路,请多包涵

由于 ES6 类只是 JavaScript 现有的基于原型的继承 [1]语法糖, 因此(IMO)提升它的定义是有意义的:

 var foo = new Foo(1, 2); //this works

function Foo(x, y) {
   this.x = x;
   this.y = y;
}

但以下将不起作用:

 var foo = new Foo(1, 2); //ReferenceError

class Foo {
   constructor(x, y) {
      this.x = x;
      this.y = y;
   }
}

为什么 ES6 类没有被提升?

原文由 Petr Peller 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 269
2 个回答

为什么 ES6 类没有被提升?

实际上它们 提升(变量绑定在整个范围内可用)就像 letconst 一样- 它们只是没有被初始化。

提升它的定义是有意义的

不。在类定义之前使用它绝不是一个好主意。考虑这个例子

var foo = new Bar(); // this appears to work
console.log(foo.x)   // but doesn't

function Bar(x) {
    this.x = x || Bar.defaultX;
}
Bar.defaultX = 0;

并将其与

var foo = new Bar(); // ReferenceError
console.log(foo.x);

class Bar {
    constructor (x = Bar.defaultX) {
        this.x = x;
    }
}
Bar.defaultX = 0;

如您所料,这会引发错误。这是静态属性、原型混合、装饰器和所有东西的问题。这对于子类化也非常重要,当您使用一个带有未调整原型的类时,子类化在 ES5 中完全中断,但现在如果 extend ed 类尚未初始化,则会抛出错误。

原文由 Bergi 发布,翻译遵循 CC BY-SA 3.0 许可协议

虽然非提升类(在某种意义上它们的行为类似于 let 绑定)可以被认为是更可取的,因为它们导致更安全的使用(参见 Bergi 的回答),但在 2ality 博客上找到的以下解释似乎提供了此实现的一个更根本的原因:

这种限制 [ 非提升] 的原因是类可以有一个 extends 子句,其值为任意表达式。该表达式必须在正确的“位置”进行评估,不能提升其评估。

原文由 Oliver Sieweke 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏