ES2015(ES6)`class`语法提供了哪些好处? [关闭]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES2015(ES6)`class`语法提供了哪些好处? [关闭]相关的知识,希望对你有一定的参考价值。
我对ES6课程有很多疑问。
使用class
语法有什么好处?我读到公共/私有/静态将成为ES7的一部分,这是一个原因吗?
而且,class
是一种不同的OOP还是它仍然是javascript的典型继承?我可以使用.prototype
修改它吗?或者它只是相同的对象,但有两种不同的方式来声明它。
有速度的好处吗?如果你有一个像大应用程序这样的大应用程序,可能更容易维护/理解?
无论你做什么,它(几乎)完全取决于你。新的class
东西大多只是语法糖。 (但是,你知道,那种好糖。)ES2015-ES2018中没有任何东西可以用class
来做你无法用构造函数和Reflect.construct
(包括继承Error
和Array
¹)。 (在ES2019或ES2020中你可以用class
做一些你不能做的事情:private fields和private methods。)
而且,
class
是一种不同的OOP还是它仍然是JavaScript的典型继承?
它与我们一直拥有的原型继承相同,如果您喜欢使用构造函数(new Foo
等),只需使用更清晰,更方便的语法。 (特别是在从Array
或Error
派生的情况下,你在ES5及更早版本中无法做到。你现在可以使用Reflect.construct
[spec,MDN],但不能使用旧的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`语法提供了哪些好处? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章