ES2015(ES6)`class`语法提供了哪些好处? [关闭]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES2015(ES6)`class`语法提供了哪些好处? [关闭]相关的知识,希望对你有一定的参考价值。

我对ES6课程有很多疑问。

使用class语法有什么好处?我读到公共/私有/静态将成为ES7的一部分,这是一个原因吗?

而且,class是一种不同的OOP还是它仍然是javascript的典型继承?我可以使用.prototype修改它吗?或者它只是相同的对象,但有两种不同的方式来声明它。

有速度的好处吗?如果你有一个像大应用程序这样的大应用程序,可能更容易维护/理解?

答案

无论你做什么,它(几乎)完全取决于你。新的class东西大多只是语法糖。 (但是,你知道,那种好糖。)ES2015-ES2018中没有任何东西可以用class来做你无法用构造函数和Reflect.construct(包括继承ErrorArray¹)。 (在ES2019或ES2020中你可以用class做一些你不能做的事情:private fieldsprivate methods。)

而且,class是一种不同的OOP还是它仍然是JavaScript的典型继承?

它与我们一直拥有的原型继承相同,如果您喜欢使用构造函数(new Foo等),只需使用更清晰,更方便的语法。 (特别是在从ArrayError派生的情况下,你在ES5及更早版本中无法做到。你现在可以使用Reflect.construct [specMDN],但不能使用旧的ES5风格。)

我可以使用.prototype修改它吗?

是的,一旦你创建了类,你仍然可以在类的构造函数上修改prototype对象。例如,这是完全合法的:

class Foo {
    constructor(name) {
        this.name = name;
    }

    test1() {
        console.log("test1: name = " + this.name);
    }
}
Foo.prototype.test2 = function() {
    console.log("test2: name = " + this.name);
};

有速度的好处吗?

通过为此提供特定的习惯用语,我认为引擎可能能够更好地进行优化。但他们已经非常善于优化,我不希望有显着的差异。

ES2015(ES6)class语法提供了哪些好处?

简而言之:如果你不首先使用构造函数,更喜欢使用Object.create或类似函数,class对你没用。

如果你使用构造函数,class有一些好处:

  • 语法更简单,更不容易出错。
  • 使用新语法而不是旧语法设置继承层次结构要容易得多(而且容易出错)。
  • class保护您免受未使用new和构造函数的常见错误(如果this不是构造函数的有效对象,则使构造函数抛出异常)。
  • 使用新语法(super.method()而不是ParentConstructor.prototype.method.call(this)Object.getPrototypeOf(Object.getPrototypeOf(this)).method.call(this))调用父原型的方法版本要简单得多。

这是层次结构的语法比较:

// ***ES2015+**
class Person {
    constructor(first, last) {
        this.first = first;
        this.last = last;
    }

    personMethod() {
        // ...
    }
}

class Employee extends Person {
    constructor(first, last, position) {
        super(first, last);
        this.position = position;
    }

    employeeMethod() {
        // ...
    }
}

class Manager extends Employee {
    constructor(first, last, position, department) {
        super(first, last, position);
        this.department = department;
    }

    personMethod() {
        const result = super.personMethod();
        // ...use `result` for something...
        return result;
    }

    managerMethod() {
        // ...
    }
}

例:

// ***ES2015+**
class Person {
    constructor(first, last) {
        this.first = first;
        this.last = last;
    }

    personMethod() {
        return `Result from personMethod: this.first = ${this.first}, this.last = ${this.last}`;
    }
}

class Employee extends Person {
    constructor(first, last, position) {
        super(first, last);
        this.position = position;
    }

    personMethod() {
        const result = super.personMethod();
        return result + `, this.position = ${this.position}`;
    }

    employeeMethod() {
        // ...
    }
}

class Manager extends Employee {
    constructor(first, last, position, department) {
        super(first, last, position);
        this.department = department;
    }

    personMethod() {
        const result = super.personMethod();
        return result + `, this.department = ${this.department}`;
    }

    managerMethod() {
        // ...
    }
}

const m = new Manager("Joe", "Bloggs", "Special Projects Manager", "Covert Ops");
console.log(m.personMethod());
另一答案

ES6类是我们今天使用的原型类系统的语法糖。它们使您的代码更简洁,自我记录,这是使用它们的理由(在我看来)。

使用Babel来转换这个ES6类:

class Foo {
  constructor(bar) {
    this._bar = bar;
  }

  getBar() {
    return this._bar;
  }
}

会给你这样的东西:

var Foo = (function () {
  function Foo(bar) {    
    this._bar = bar;
  }

  Foo.prototype.getBar = function () {
    return this._bar;
  }

  return Foo;
})();

第二个版本并不复杂,维护的代码更多。当涉及到继承时,这些模式变得更加复杂。

因为这些类编译成我们一直使用的相同原型模式,所以你可以对它们进行相同的原型操作。这包括在运行时添加方法等,访问Foo.prototype.getBar上的方法等。

今天ES6中有一些基本的隐私支持,虽然它基于不导出您不想访问的对象。例如,您可以:

const BAR_NAME = 'bar';

export default class Foo {
  static get name() {
    return BAR_NAME;
  }
}

BAR_NAME将不能用于其他模块直接引用。

许多库试图支持或解决这个问题,比如Backbone和他们的extends帮助器,它使用类似方法的函数和属性的未经验证的散列,但是没有用于暴露原型继承的编组系统,不涉及原型的捣乱。

随着JS代码变得越来越复杂并且代码库越来越大,我们开始发展很多模式来处理继承和模块之类的事情。 IIFE用于创建模块的私有范围有很多括号和parens;缺少其中一个可能导致一个完全不同的有效脚本(在模块可以将下一个模块作为参数传递给它之后跳过分号,这很少有用)。

tl; dr:它是我们已经做过的糖,并且在代码中明确了你的意图。

以上是关于ES2015(ES6)`class`语法提供了哪些好处? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

es6 有哪些拓展

es6 类

ES6 Class 基础语法

js es6语法 class类 class继承 super关键字

ES6 - 基础学习: Class 类

ES6(2015)Class (类)