为什么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绑定在整个范围内可用),就像let
和const
一样 – 它们只是不被初始化。
提出它的定义是有道理的
不。在定义之前使用一个类不是一个好主意。 考虑这个例子
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对象。