являются ли классы es6 просто синтаксическим сахаром для прототипа в javascript?

После игры с ES6 мне действительно понравился класс Thing { // ... classy stuff doStuff () {} } синтаксиса и доступных функций, но у меня есть вопрос о классах.

являются ли новые классы ES6 просто синтаксическим сахаром для старого прототипа? или там больше происходит здесь за кулисами? то есть:

var Thing = function() {
  // ... setup stuff
};

Thing.prototype.doStuff = function() {}; // etc

vs:

constructor

javascript,ecmascript-6,

18

Ответов: 5


11 принят

Да, возможно, но некоторые из синтаксического сахара имеют зубы.

Объявление класса создает объект-прототип, который является классом Function.prototype для класса, используя код, предоставленный для constructorтела класса, и для именованных классов с тем же именем, что и класс.

У вызова конструктора класса есть нормальный объект приложения, из которого экземпляры класса наследуют свойства в обычном режиме JavaScript. К этой длине добавляются методы экземпляра, определенные в классе.

ES6 не предоставляет средства для объявления значений свойств по умолчанию класса экземпляра класса (т.е. значений, которые не являются методами) внутри тела класса, которые должны быть сохранены в .prototype и унаследованы. Чтобы инициализировать значение экземпляра, вы можете установить их как локальные, не наследуемые свойства внутри конструктора или вручную добавить их к prototypeобъекту конструктора класса вне определения класса так же, как и для обычных функций конструктора. (Я не утверждаю, что по существу или иным образом создаю унаследованные свойства для классов JavaScript).

Статические методы, объявленные внутри тела класса, добавляются как свойства функции конструктора классов. Избегайте использования имен методов статического класса, которые конкурируют со стандартными функциональными свойствами и методами, унаследованными от, prototypeнапример prototype, Object.createили Function.

Менее сладким является то, что объявления и методы класса всегда выполняются в строгом режиме, а функция, которая получает мало внимания: Object.setPrototypeOfсвойство функций конструктора классов читается только: вы не можете установить его на какой-либо другой объект, который вы создали для некоторых специальных цель.

Некоторые интересные вещи случаются, когда вы расширяете класс:

  • prototypeсвойство объекта расширенного конструктору класса автоматически на прототип prototypeобъекта класса расширяется. Это не является особенно новым, и эффект можно дублировать с помощью childClass.__proto__ = parentClass.

  • функция конструктора расширенного класса (объект) автоматически прототипируется в функции конструктора расширенного класса, а не Function. Хотя может быть возможно воспроизвести влияние на обычную конструкторскую функцию, используя functionили даже , это будет чрезвычайно необычная практика кодирования и часто не рекомендуется в документации JavaScript.class Thing { someFunc() {} } console.log("someFunc" in Thing.prototype); // true

Существуют и другие отличия, такие как объекты класса, которые не поднимаются в виде названных функций, объявленных с использованием functionключевого слова.

Я считаю, что наивно полагать, что объявления и выражения класса будут оставаться неизменными во всех будущих версиях сценария ECMA, и будет интересно узнать, происходят ли и когда происходят события. Вероятно, стало причудой ассоциировать «синтаксический сахар» с классами, введенными в ES6 (ECMA-262 стандартной версии 6), но лично я стараюсь не повторять его.


12 ов

Являются ли новые классы ES6 просто синтаксическим сахаром для старого прототипа?

Да, это просто удобный синтаксис, семантика идентична.

Классы JavaScript представлены в ECMAScript 6 и являются синтаксическим сахаром над существующим на основе прототипов на основе JavaScript. Синтаксис класса не представляет для JavaScript новую объектно-ориентированную модель наследования. Классы JavaScript обеспечивают гораздо более простой и понятный синтаксис для создания объектов и работы с наследованием.

Источник

Следующий пример короткого кода также подтверждает это.

new

11 ов

Да. Но они более строгие.

В ваших примерах есть два основных отличия.

Прежде всего, с синтаксисом класса вы не можете инициализировать экземпляр без newключевого слова.

class Thing{}
Thing() //Uncaught TypeError: Class constructor Thing cannot be invoked without 'new'

var Thing = function() {
  if(!(this instanceof Thing)){
     return new Thing();
  }
};
Thing(); //works

Второй - классы, определенные с помощью синтаксиса класса. Это похоже на определение переменных с letключевым словом.

class Thing{}
class Thing{} //Uncaught SyntaxError: Identifier 'Thing' has already been declared

{
    class Thing{}
}
console.log(Thing); //Uncaught ReferenceError: Thing is not defined

редактировать

Как упоминал @zeroflagL в своем комментарии, объявления классов также не поднимаются.

console.log(Thing) //Uncaught ReferenceError: Thing is not defined
class Thing{}

1

Это полностью синтаксический сахар. Что нового в прототипическом наследовании в ES6 - это переопределение __proto__свойства объектов. __proto__теперь является законным, и именно так стало возможным подкласс класса с JS.


0

Да, почти.

С помощью es6 вы можете расширить класс Function и класс Array, в es5 вы не можете иметь такое же поведение: расширение функции не делает вызываемый объект и расширение массива не наследует свойство auto .length в es5

Для остальных логика и классы прототипов в JavaScript одинаковы

Являются ли классы es6 действительно семантическим сахаром?

JavaScript, ECMAScript-6,
Похожие вопросы