Ответ 1
(Почти) полностью зависит от вас, используете ли вы новый синтаксис class
. В основном это просто синтаксический сахар. (Но, вы знаете, хороший вид сахара.) В ES2015-ES2018 нет ничего, что class
не может сделать, что вы не можете сделать с помощью функций конструктора и Reflect.construct
(включая создание подклассов Error
и Array
¹), (Скорее всего, is будет чем-то в ES2019 или ES2020, что вы можете сделать с class
, что вы не можете сделать иначе: частные поля и частные методы.)
Кроме того,
class
- это другой тип ООП или это все еще прототипное наследие 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);
};
Есть ли преимущества в скорости?
Предоставляя конкретную идиому для этого, я полагаю, возможно, что двигатель сможет лучше оптимизировать работу. Но они уже очень хороши в оптимизации, я бы не ожидал существенной разницы.
What benefits does ES2015 (ES6)
class
syntax provide?
Вкратце: если вы не используете функции конструктора в первую очередь, предпочитая 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());