gpt4 book ai didi

javascript - Javascript:Function和Class有什么区别

转载 作者:行者123 更新时间:2023-11-28 04:35:23 26 4
gpt4 key购买 nike

随着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;
}


那么,使用类而不是传统函数有什么好处?
在什么情况下我应该使用类而不是函数?

最佳答案

类和函数之间有一些区别-大多数人会从说类只是“语法糖”开始,但是糖确实起了很大的作用。当JS解析器处理JavaScript代码时,解析器会将它们保存在不同的AST节点中,如下所示,在最终的AST树中,ClassDeclaration和ClassExpression是不同的节点类型:

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
};


这是因为当解析器遇到类-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类中的私有属性,有一个单独的答案,这建议了一些解决方法,例如使用Symbols:

Private properties in JavaScript ES6 classes

var property = Symbol(); // private property workaround example
class Something {
constructor(){
this[property] = "test";
}
}


当然,类和函数之间存在更多差异。其中之一是提升 1-与Function不同,您不能在范围的任何地方声明Class:


  函数声明和类之间的重要区别
  声明是函数声明被悬挂并且是类
  声明不是。您首先需要声明您的课程,然后
  访问它


类声明和函数声明非常相似。

function foo1() {} // can be used before declaration
class foo2{} // new foo2(); works only after this declaration


类表达式的作用与函数表达式非常相似,例如,可以将它们分配给变量:

var myClass = class foobar {};


1还有更多区别


类表达式/声明主体始终在严格模式下执行-无需手动指定
类具有特殊的关键字构造函数-只能有一个关键字构造函数,否则会引发错误。函数可以具有名为“构造函数”的函数变量的多个定义
类具有与父类构造函数有关的特殊关键字super。如果您在构造函数内部,则可以调用super(x,y);调用父类的构造函数,但是在Method内部,可以调用super.foobar()创建对任何父类函数的调用。这种功能不适用于标准功能,尽管您可以通过一些自定义骇客来模仿它。
在类主体内部,您可以使用static关键字定义函数,因此只能使用ClassName.FunctionName()-syntax进行调用。
类的声明和表达式都可以使用extends关键字,例如,Dog狗的扩展Animal
MethodDeclaration不需要函数-prefix,因此您可以在类“ m”内定义函数“ ok”,如下所示:类m {ok(){}}。实际上甚至不允许将函数定义为类m {function ok(){}}


但是,在解析器完成其工作之后,该类实例实际上将以与其他任何对象相同的方式运行。

新的ES6类语法从本质上讲是一种更清晰的方式,以传统的OOP方式表达对象,如果喜欢,则应使用它。

编辑:而且,ES6类语法也有另一个限制:它不允许成员函数使用通过胖箭头进行词法绑定。 ES7似乎允许 experimental feature允许它。例如,当将方法绑定到事件处理程序时,这可能很有用,相关的问题是 here

1 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

关于javascript - Javascript:Function和Class有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44258655/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com