由于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课程?
答案 0 :(得分:50)
为什么不提升ES6课程?
实际上他们 被提升(变量绑定在整个范围内可用),就像let
and const
are一样 - 它们只是没有初始化。
提升其定义
是有意义的
没有。在定义之前使用类永远不是一个好主意。考虑一下这个例子
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;
会像您期望的那样抛出错误。这是静态属性,原型mixins,装饰器和一切的问题。此外,对于子类化非常重要,当你使用带有非调整原型的类时,它完全在ES5中破坏,但是如果extend
ed类尚未初始化,则会抛出错误。
答案 1 :(得分:4)
在Javascript中,所有声明(var,let,const,function,function *,class)都悬挂,但应在相同范围中声明。
正如你所说的“ES6类只是JavaScript现有的基于原型的继承的语法糖”
那么让我们理解它是什么?
这里你声明了一个实际上是“特殊功能”的类。让我们假设你的函数Foo()和类Foo都在全局范围内。
class Foo {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
以下是您的类Foo的编译代码。
var Foo = (function () {
function Foo(x, y) {
this.x = x;
this.y = y;
}
return Foo;
}());
在内部,您的类在包装函数(iife)中转换为具有相同名称的函数,并且该包装函数将返回您的函数。
因为您的函数(类)范围已更改。并且您正试图在全局范围内创建功能对象,而实际上并不存在。
一旦编译完成,你就会在变量Foo中得到函数。所以稍后你在var中有了函数你可以创建它的对象。
答案 2 :(得分:1)
虽然非悬挂类(在某种意义上表现得像let
绑定)可以被认为是更可取的,因为它们会导致更安全的使用(请参见Bergi's answer),在{ {3}}博客似乎提供了此实现的一些更基本的原因:
此限制[非提升]的原因是,类可以具有一个
extends
子句,该子句的值可以是任意表达式。该表达式必须在正确的“位置”进行评估,其评估无法进行。
答案 3 :(得分:0)
类不会被提升,因为例如当一个类扩展一个表达式而不是一个函数时,就会发生错误:
class Dog extends Animal {}
var Animal = function Animal() {
this.move = function () {
alert(defaultMove);
}
}
var defaultMove = "moving";
var dog = new Dog();
dog.move();
吊装后会变成:
var Animal, defaultMove, dog;
class Dog extends Animal {}
Animal = function Animal() {
this.move = function () {
alert(defaultMove);
}
}
defaultMove = "moving";
dog = new Dog();
dog.move();
在Dog 扩展Animal 类被解释为Animal 实际上未定义的地方,我们得到一个错误。我们可以通过在 Dog 的声明之前移动 Animal 表达式来轻松解决这个问题。 请看这篇关于该主题的精彩文章: https://blog.thoughtram.io/angular/2015/09/03/forward-references-in-angular-2.html