首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >JavaScript:函数和类有什么区别?

JavaScript:函数和类有什么区别?
EN

Stack Overflow用户
提问于 2018-10-29 00:24:41
回答 2查看 0关注 0票数 0

随着2015年6月ECMAScript 6的发布,引入了Javascript类语法。

这个语法:

代码语言:javascript
复制
class Polygon {
      constructor(width, height) {
        this.width = width;
        this.height = height;
      }
}

基本相同:

代码语言:javascript
复制
function Polygon(width, height) {
    this.width = width;
    this.height = height;
}

那么使用类而不是传统函数有什么好处呢?在什么条件下我应该使用类而不是函数?

EN

回答 2

Stack Overflow用户

发布于 2018-10-29 09:09:54

class它只不过是使用javascript逻辑类创建的语法糖function。如果你正在使用afunction作为class整个函数充当构造函数,如果你想在构造函数中使用其他成员函数this.something = ...,或者var something = ...在私有成员的情况下(如果你不是从外部注入,假设你是使用其他方法/属性创建对象),但是在类的情况下,整个函数实际上不是构造函数,可以将其与其他成员函数和数据明确地分开。

票数 0
EN

Stack Overflow用户

发布于 2018-10-29 09:51:57

类和函数之间存在一些差异 - 大多数人会首先说类是“只是语法糖”,但糖确实很重要。当JS解析器处理JavaScript代码时,解析器会将它们保存在不同的AST节点中,如此处所示,ClassDeclarationClassExpression是生成的AST树中的不同节点类型:

https://github.com/estree/estree/blob/master/es2015.md#classes

您可以看到,对于此解析器,新的ES6 Classes规范在语法中引入了许多新的AST元素:

  • ClassBody
  • MethodDefinition
  • ClassDeclaration
  • ClassExpression
  • 元属性

由于AST语法不是标准的,因此可能有更多或更少的类型,具体取决于解析器,但重要的是要注意,当代码进入类声明或类表达式时,它将由JavaScript引擎以不同方式进行解释。

这意味着,无法交换类和函数声明。如果你试着写,你可以看到这个

代码语言:javascript
复制
class notWorking {
  return 1;  // <-- creates a parser error
};

这是因为当解析器遇到类-keyword时,它将开始将以下代码视为ClassDeclaration或ClassExpression的ClassBody,然后它会查找MethodDefinitions。

这是一个小问题,因为创建私有变量会变得更具挑战性。函数声明可以像这样整齐地定义一个私有变量:

代码语言:javascript
复制
function myClass() {
    var privateVar;
}

类声明不能有这个:

代码语言:javascript
复制
class myClass {
    var privateVar; // ERROR: should be a method
}

这是因为class的语法只允许在类体内声明方法。至少现在。

但是,存在创建私有字段的提议:

https://github.com/zenparsing/es-private-fields

因此,将来你可能会说

代码语言:javascript
复制
class myClass {
   #privateVar; // maybe this works in the future?
}

考虑到ES6类中的私有属性,有一个单独的答案,它提出了一些解决方法,比如使用符号:

JavaScript ES6类中的私有属性

代码语言:javascript
复制
var property = Symbol(); // private property workaround example
class Something {
    constructor(){
        this[property] = "test";
    }
}

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

函数声明和类声明之间的一个重要区别是函数声明被提升而类声明不被提升。首先需要声明您的类然后访问它

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

代码语言:javascript
复制
function foo1() {} // can be used before declaration
class  foo2{}      // new foo2(); works only after this declaration

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

代码语言:javascript
复制
var myClass = class foobar {};

更多的差异是1

  1. Class exression /声明体总是在Strict模式下执行- 无需手动指定
  2. 类具有特殊的关键字构造函数 - 只能有一个,或者抛出错误。函数可以有多个名为“constructor”的函数变量定义
  3. 类具有特殊关键字super,它与父类构造函数相关。如果你在构造函数中,你可以调用super(x,y); 要调用父类构造函数,但在Method中,可以调用super.foobar()来创建对任何父类函数的调用。这种功能不适用于标准功能,尽管您可以通过一些自定义黑客来模拟它。
  4. 在类体内部,您可以使用static关键字定义函数,因此只能使用ClassName.FunctionName()-syntax 调用它。
  5. 这两个类的声明和表达式可以使用扩展关键词中包含Dog类扩展动物
  6. MethodDeclaration不需要函数-prefix,因此你可以在类“m”中定义函数“ok”,如下所示:class m {ok(){}}。实际上甚至不允许将函数定义为类m {function ok(){}}

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

新的ES6 Class语法本质上是以传统的OOP方式表达对象的更清晰的方式,如果你喜欢它,那么你应该使用它。

编辑:此外,ES6类语法还有另一个限制:它不允许成员函数使用胖箭头进行词法绑定。ES7似乎有实验性功能允许它。例如,当将方法绑定到事件处理程序时,这可能很有用,相关问题就在这里

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100006176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档