Class 和 Function 之间有一些区别——大多数人会首先说 Class 是“只是语法糖”,但这种糖确实很重要。当 JS 解析器处理 JavaScript 代码时,解析器会将它们保存在不同的 AST 节点中,如下所示,ClassDeclaration和ClassExpression在生成的 AST 树中是不同的节点类型:
https://github.com/estree/estree/blob/master/es2015.md#classes
你可以看到,对于这个解析器,新的 ES6 Classes 规范在语法中引入了许多新的 AST 元素:
由于 AST 语法不是标准的,根据解析器可以有更多或更少的类型,但重要的是要注意,当代码进入类声明或类表达式时,JavaScript 引擎会对其进行不同的解释。
这意味着不能交换 Class 和 Function 声明。如果您尝试编写,您可以看到这一点
class notWorking {
return 1; // <-- creates a parser error
};
这是因为当解析器遇到 class -keyword 时,它将开始将以下代码视为 ClassDeclaration 或 ClassExpression 的 ClassBody,然后它期望找到 MethodDefinitions。
这是一个小问题,因为创建私有变量变得更具挑战性。函数声明可以像这样巧妙地定义一个私有变量:
function myClass() {
var privateVar;
}
类声明不能有这个:
class myClass {
var privateVar; // ERROR: should be a method
}
这是因为类的语法只允许在类体内声明方法。至少现在是这样。
但是,存在创建私有字段的提议:
https://github.com/zenparsing/es-private-fields
因此,将来你可能会说
class myClass {
#privateVar; // maybe this works in the future?
}
考虑到 ES6 类中的私有属性,有一个单独的答案,它提出了一些解决方法,例如使用符号:
JavaScript ES6 类中的私有属性
var property = Symbol(); // private property workaround example
class Something {
constructor(){
this[property] = "test";
}
}
当然,类和函数之间存在更多差异。其中之一是提升 1 - 与函数不同,您不能在范围内的任何地方声明类:
函数声明和类声明之间的一个重要区别是函数声明被提升而类声明不是。您首先需要声明您的类,然后访问它
类声明和函数声明非常相似;
function foo1() {} // can be used before declaration
class foo2{} // new foo2(); works only after this declaration
类表达式的工作方式与函数表达式非常相似,例如它们可以分配给变量:
var myClass = class foobar {};
更多的差异是1
- Class 表达式/声明体总是在严格模式下执行- 无需手动指定
- 类有特殊的关键字构造函数——只能有一个,否则会抛出错误。函数可以有多个名为“构造函数”的函数变量定义
- 类具有与父类构造函数相关的特殊关键字super。如果你在构造函数中,你可以调用super(x, y); 要调用父类构造函数,但在 Method 内部,您可以调用super.foobar()来创建对任何父类函数的调用。这种功能不适用于标准函数,尽管您可以使用一些自定义黑客来模拟它。
- 在类体内,您可以使用static关键字定义函数,因此可以仅使用ClassName.FunctionName() -syntax来调用它。
- 类声明和表达式都可以使用extends关键字,如class Dog extends Animal
- MethodDeclaration 不需要函数前缀,因此您可以在类“m”中定义函数“ok”,如下所示:class m { ok() { } }。实际上甚至不允许将函数定义为class m { function ok() { } }
然而,在解析器完成它的工作后,类实例本质上与任何其他对象以相同的方式运行。
新的 ES6 Class 语法本质上是更清晰的以传统 OOP 方式表达对象的方式,如果你喜欢它,那么你应该使用它。
编辑:此外,ES6 类语法还有另一个限制:它不允许成员函数使用使用粗箭头进行词法绑定。ES7 似乎具有允许它的实验性功能。例如,当将方法绑定到事件处理程序时,这可能很有用,相关问题是here。
1 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes