Разница в том, что при создании с class
объект prototype
устанавливается на writable: false
, поэтому вы не можете заменить Pet.prototype
присвоением.Вы можете увидеть эту разницу в вашем Object.getOwnPropertyDescriptor()
вызове при удалении строгого режима.
Первый пример кода OP показывает это:
{
...
"writable": true,
"enumerable": false,
"configurable": false
}
Второй пример кода OP показывает это:
{
...
"writable": false,
"enumerable": false,
"configurable": false
}
Свойство writable
определяет, может ли свойство Pet.prototype
быть присвоено новое значение или нет (например, заменено новым объектом).Значение false
означает, что вы не можете заменить Pet.prototype
, используя присвоение.Поэтому, когда ваш код пытается это сделать, он терпит неудачу.
Вы по-прежнему можете добавлять или удалять отдельные свойства объекта-прототипа, просто не заменяя весь объект.Это имеет некоторый смысл для меня, потому что замена всего объекта-прототипа отменяет все определение class
.Возможно, вы могли бы изменить объект Pet.prototype
для записи, если бы у вас была реальная причина заменить его.
Это описано в спецификации ES 2015.В 14.5.14 Семантика времени выполнения: ClassDefinitionEvaluation , на шаге 16 она делает это:
Perform MakeConstructor (F, false, proto).
Этот аргумент false
делает созданный прототип недоступным для записи (поэтому его нельзя заменить).
И, если вы посмотрите на 9.2.8 MakeConstructor () , вы увидите это на шаге 6:
Пусть status будет DefinePropertyOrThrow (F, "prototype ", PropertyDescriptor {[[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false}).
ГдеАтрибут writable
получает значение false
, которое ему ранее было передано.
Часто утверждается, что классы ES2015 являются просто "синтаксическим сахаром" поверх функций конструктора ES5.и наследование на основе прототипа.Но это различие в поведении ...
Хотя общая работа методов, определенных в class
, почти одинакова, этот другой ответ описывает несколько других различий между использованием class
по сравнению с ручным назначением прототипа: В javascript, чем отличаются класс и конструктор?