Куда записывается свойство при добавлении его в прототип объекта в JavaScript
Что проверяют
Понимаете ли вы, что прототип это отдельный живой объект, на который ссылаются экземпляры, а не шаблон, копируемый при создании. Следом почти всегда спрашивают, что будет, если присвоить то же свойство экземпляру, и чем опасно класть в прототип массив.
Как отвечать
Свойство записывается в сам объект прототипа, например в Person.prototype, и только туда. Своего свойства у экземпляров не появляется: у них есть внутренняя ссылка [[Prototype]], по которой идёт поиск.
- чтение: движок ищет свойство у самого объекта, затем идёт по цепочке прототипов до
Object.prototypeи дальше доnull, где возвращаетundefined; - живая связь: прототип не копируется, поэтому свойство, добавленное после создания экземпляров, сразу видно и у них;
- запись в экземпляр:
john.age = 40создаёт собственное свойство уjohn, и оно затеняет прототипное. Прототип и другие экземпляры не меняются. Исключения: если в прототипе для этого имени есть сеттер, вызовется он, а если свойство в прототипе объявлено сwritable: false, присваивание не сработает, в строгом режиме сTypeError; - проверка:
Object.hasOwn(john, "age")илиhasOwnPropertyотличает своё свойство от унаследованного, операторinсмотрит всю цепочку; - классы: методы экземпляра попадают в
Class.prototype, а поля класса (count = 0, стрелочные функции в полях) создаются на каждом экземпляре заново.
Прототип читают через Object.getPrototypeOf(obj), а __proto__ оставлен только для совместимости.
Где спотыкаются
Кладут в прототип изменяемое значение: Person.prototype.tags = []. Вызов john.tags.push("a") меняет общий массив, потому что это не присваивание, а мутация найденного по цепочке объекта, и новый элемент появляется у всех экземпляров.
Говорят, что при new свойства прототипа копируются в объект. Тогда нельзя объяснить, почему метод, добавленный позже, виден у старых экземпляров.
Путают prototype и [[Prototype]]. Первое есть у функций-конструкторов и классов и становится прототипом создаваемых объектов, второе есть у каждого объекта и указывает на его прототип.