Давайте рассмотрим некоторые, возможно, сбивающие с толку концепции в книге.
Во-первых, наверху каждой нормальной цепочки [[Prototype]]
находится встроенный объект Object.prototype
. Кроме того, все обычные (встроенные, не зависящие от хоста) объекты в JS происходят от объекта Object.prototype
.
Рассмотрим этот код: myObject.foo = "bar"
Давайте рассмотрим сценарии, которые немного сбивают с толку, когда foo
еще не находится на myObject
напрямую, но находится на более высоком уровне цепочки [[Prototype]] myObject
.
Прежде чем мы перейдем к этому, давайте напомним себе, что средство доступа к данным (было объяснено в главе 3)
Рассмотрим этот код: var myObject = { a:2 };
Свойство a
является средством доступа к данным или дескриптором, поскольку это свойство имеет значение, которое может быть writable:true
или нет. Это просто для хранения значения данных. Это в отличие от дескриптора доступа, который является свойством, описываемым геттером-установщиком. Для дескрипторов доступа значение и доступные для записи характеристики дескриптора игнорируются.
Теперь, когда мы разобрались с этим, приступим:
1. Если свойство средства доступа к данным с именем foo
находится где-то выше в цепочке [[Prototype]] и для него установлено значение true, то новое свойство с именем foo
добавляется непосредственно в myObject
, что приводит к теневому свойству.
2. Если foo
находится выше в цепочке [[Prototype]]
, но помечен как writable:false
(только для чтения), то как установка этого существующего свойства, так и создание затененного свойства на myObject
запрещены. Если код выполняется в строгом режиме, будет выдана ошибка, иначе установка значения свойства будет автоматически проигнорирована. Здесь никогда не бывает затенения.
Второй случай не очень интуитивно понятен, потому что, когда свойство находится выше в цепочке прототипов и доступно только для чтения, почему не должно быть настройки свойства, foo
в нашем случае, на myObject
. Кайл объясняет причину, говоря: «Причина этого ограничения в первую очередь состоит в том, чтобы усилить иллюзию свойств, наследуемых классом. Если вы думаете, что foo
на более высоком уровне цепочки унаследовано (скопировано) на myObject
, тогда имеет смысл принудительно установить запрет на запись этого свойства foo
на myObject
. Однако если вы отделите иллюзию от факта и признаете, что такое копирование наследования на самом деле не происходило (см. Главы 4 и 5), это немного неестественно, что myObject
не сможет иметь свойство foo
только потому, что на каком-то другом объекте было не записываемое foo
".
На этом пока все ❤️