随着2015年6月ECMAScript 6的发布,引入了Javascript类语法。
这个语法:
class Polygon {
constructor(width, height) {
this.width = width;
this.height = height;
}
}
基本相同:
function Polygon(width, height) {
this.width = width;
this.height = height;
}
那么使用类而不是传统函数有什么好处呢?在什么条件下我应该使用类而不是函数?
发布于 2018-10-29 09:51:57
类和函数之间存在一些差异 - 大多数人会首先说类是“只是语法糖”,但糖确实很重要。当JS解析器处理JavaScript代码时,解析器会将它们保存在不同的AST节点中,如此处所示,ClassDeclaration和ClassExpression是生成的AST树中的不同节点类型:
https://github.com/estree/estree/blob/master/es2015.md#classes
您可以看到,对于此解析器,新的ES6 Classes规范在语法中引入了许多新的AST元素:
由于AST语法不是标准的,因此可能有更多或更少的类型,具体取决于解析器,但重要的是要注意,当代码进入类声明或类表达式时,它将由JavaScript引擎以不同方式进行解释。
这意味着,无法交换类和函数声明。如果你试着写,你可以看到这个
class notWorking {
return 1; // <-- creates a parser error
};
这是因为当解析器遇到类-keyword时,它将开始将以下代码视为ClassDeclaration或ClassExpression的ClassBody,然后它会查找MethodDefinitions。
这是一个小问题,因为创建私有变量会变得更具挑战性。函数声明可以像这样整齐地定义一个私有变量:
function myClass() {
var privateVar;
}
类声明不能有这个:
class myClass {
var privateVar; // ERROR: should be a method
}
这是因为class的语法只允许在类体内声明方法。至少现在。
但是,存在创建私有字段的提议:
https://github.com/zenparsing/es-private-fields
因此,将来你可能会说
class myClass {
#privateVar; // maybe this works in the future?
}
考虑到ES6类中的私有属性,有一个单独的答案,它提出了一些解决方法,比如使用符号:
var property = Symbol(); // private property workaround example
class Something {
constructor(){
this[property] = "test";
}
}
当然,类和函数之间存在更多差异。其中一个是Hoisting 1 - 与Functions不同,你不能在范围内的任何地方声明Class:
函数声明和类声明之间的一个重要区别是函数声明被提升而类声明不被提升。首先需要声明您的类然后访问它
类声明和函数声明非常相似;
function foo1() {} // can be used before declaration
class foo2{} // new foo2(); works only after this declaration
类表达式与函数exressions的工作方式非常相似,例如可以将它们分配给变量:
var myClass = class foobar {};
更多的差异是1
但是,在解析器完成它的工作之后,类实例基本上以与任何其他对象相同的方式运行。
新的ES6 Class语法本质上是以传统的OOP方式表达对象的更清晰的方式,如果你喜欢它,那么你应该使用它。
编辑:此外,ES6类语法还有另一个限制:它不允许成员函数使用胖箭头进行词法绑定。ES7似乎有实验性功能允许它。例如,当将方法绑定到事件处理程序时,这可能很有用,相关问题就在这里。
1 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
https://stackoverflow.com/questions/-100006176
复制相似问题