为什么ES6课堂没有悬挂?

由于ES6类仅仅是JavaScript现有的基于原型的inheritance的一种语法糖 [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课程没有悬挂?

为什么ES6课程没有悬挂?

实际上,它们挂起(variables绑定在整个范围内可用),就像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类还没有初始化,现在会抛出一个错误。

在Javascript中,所有的声明(var,let,const,function,function *,class)都被挂起,但是它应该在同一个范围内声明。

正如你所说的,“ES6类仅仅是JavaScript的现有基于原型的inheritance的语法糖”

那么让我们了解它是什么?

在这里你声明了一个实际上是“特殊函数”的类。让我们假设你的函数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)中相同名称的函数,并且包装函数返回你的函数。

因为你的函数的(类)范围被改变了。 而你正试图在全球范围内创造实际上不存在的function对象。

一旦编译完成,你就可以在variablesFoo中得到这个函数。 所以后来你在var函数中可以创build对象。