gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 02:18:47 28 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节点中,如下所示, ClassDeclaration ClassExpression 是结果AST树中的不同节点类型:

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

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

  • ClassBody
  • 方法定义
  • 类声明
  • ClassExpression
  • MetaProperty

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

    这意味着不能交换Class和Function声明。如果您尝试写,可以看到此内容
    class notWorking {
    return 1; // <-- creates a parser error
    };

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

    这是一个小问题,因为创建私有(private)变量变得更具挑战性。函数声明可以整齐地定义一个私有(private)变量,如下所示:
    function myClass() {
    var privateVar;
    }

    类声明不能具有以下内容:
    class myClass {
    var privateVar; // ERROR: should be a method
    }

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

    但是,存在创建私有(private)字段的建议:

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

    因此,将来您可能会说
    class myClass {
    #privateVar; // maybe this works in the future?
    }

    考虑到ES6类中的私有(private)属性,有一个单独的答案,这建议了一些解决方法,例如使用Symbols:

    Private properties in JavaScript ES6 classes
    var property = Symbol(); // private property workaround example
    class Something {
    constructor(){
    this[property] = "test";
    }
    }

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

    An important difference between function declarations and class declarations is that function declarations are hoisted and class declarations are not. You first need to declare your class and then access it



    类声明和函数声明非常相似。
    function foo1() {} // can be used before declaration
    class foo2{} // new foo2(); works only after this declaration

    类表达式的作用与函数表达式非常相似,例如,可以将它们分配给变量:
    var myClass = class foobar {};

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

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

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

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

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

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

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