Почему расширенные классы используют прототипы для методов, а не для полей?
Глядя на этот простой код:
class Animal {
someField = 42;
animalFunc() {
console.log('animal')
}
}
class Lion extends Animal {
lionFunc() {
console.loge('lion')
}
}
let lion = new Lion();
console.log(lion)
Результат в Chrome:
Как мы видим, методы экземпляра находятся на прототипе (для каждой функции-конструктора)
Вопрос:
Почему полей, в отличие от методов, нет на прототипе?
Я имею в виду ,
someField
в
Animal
не в
Lion
.
1 ответ
Это предполагаемое поведение, как показано в ECMAScript — 15.7.14 Семантика времени выполнения: ClassDefinitionEvaluation
25.f
:
f. Else if element is a ClassFieldDefinition Record, then
i. If IsStatic of e is false, append element to instanceFields.
ii. Else, append element to staticElements.
И в
29.
:
Set F.[[Fields]] to instanceFields.
Итак, после того, как мы увидим, что это не ошибка, давайте посмотрим, почему:
Простыми словами:
Как мы знаем, если бы у нас была функция в прототипе и мы изменили значение этой функции, оно было бы изменено для всех.
Если мы поместим свойство в прототип и какой-то экземпляр изменит значение свойства, это изменит значение свойства и в других экземплярах, и, естественно, такого поведения не должно происходить, поэтому мы помещаем свойства в сам экземпляр.
Для статических свойств это предполагаемое поведение, поскольку у нас есть только один их экземпляр, поэтому они находятся в прототипе.
Дополнительный:
этот комментарий Ранандо Д. Вашингтон-Кинга из предложения полей класса
Цитата, которую я упоминаю, касается проблемы добавления
x
свойство данных к прототипу [...]:
Каждый экземпляр имеет копию объекта. Ожидание может быть, а может и не быть именно таким. Рассмотрим в Java возможность определять вложенные классы. В этом случае определенно желательно, чтобы каждый экземпляр мог видеть одно и то же определение класса. С другой стороны, рассмотрите возможность назначения пустого массива. Вероятное намерение состоит в том, чтобы каждый экземпляр имел свою собственную копию этого массива для хранения значений, специфичных для экземпляра.