JavaScript. Подробное руководство, 6-е издание
<b>var len = book && book.subtitle && book.subtitle.length;</b>Чтобы понять, почему второе выражение позволяет предотвратить появление исключений
, можете вернуться к описанию короткой схемы вычислений, используемой оператором<b>ТуреЕrror</b>, в разделе 4.10.1. Разумеется, попытка установить значение свойства для значения<b>&&</b>или<b>null</b>также вызывает исключение<b>undefined</b>.<b>ТуреЕrror</b>Попытки установить значение свойства для других значений не всегда оканчиваются успехом: некоторые свойства доступны только для чтения и не позволяют изменять их значения. Кроме того, некоторые объекты не позволяют добавлять в них новые свойства. Однако самое интересное, что подобные неудачи, как правило, не приводят к возбуждению исключения:
<b>// Свойства prototype встроенных конструкторов доступны только для чтения.</b><b>Object.prototype = 0; // Присваивание не возбудит исключения;</b><b> // значение Object.prototype не изменится</b>Этот исторически сложившийся недостаток JavaScript исправлен в строгом режиме, определяемом стандартом ECMAScript 5. Все неудачные попытки изменить значение свойства в строгом режиме приводят к исключению
.<b>ТуреЕrror</b>Правила, позволяющие определить, когда попытка выполнить операцию присваивания завершится успехом, а когда неудачей, просты и понятны, но их сложно выразить в достаточно краткой форме. Попытка присвоить значение свойству р объекта о потерпит неудачу в следующих случаях:
• Объект
имеет собственное свойство<b>о</b>, доступное только для чтения: нельзя изменить значение свойства, доступного только для чтения. (Обратите, однако, внимание на метод<b>р</b>который представляет собой исключение, позволяющее изменять значения настраиваемых свойств, доступных только для чтения.)<b>defineProperty(),</b>• Объект
имеет унаследованное свойство<b>о</b>, доступное только для чтения: унаследованные свойства, доступные только для чтения, невозможно переопределить собственными свойствами с теми же именами.<b>р</b>• Объект
не имеет собственного свойства<b>о</b>; объект<b>р</b>не наследует свойство<b>о</b>с методами доступа и атрибут<b>р</b>(раздел 6.8.3) объекта<b>extensible</b>имеет значение<b>о</b>. Если свойство<b>false</b>отсутствует в объекте<b>р</b>и для него не определен метод записи, то операция присваивания попытается добавить свойство<b>о</b>в объект<b>р</b>. Но поскольку объект<b>о</b>не допускает возможность расширения, то попытка добавить в него новое свойство потерпит неудачу.<b>о</b>6.3. Удаление свойств
Оператор
(раздел 4.13.3) удаляет свойство из объекта. Его единственный операнд должен быть выражением обращения к свойству. Может показаться удивительным, но оператор<b>delete</b>не оказывает влияния на значение свойства - он оперирует самим свойством:<b>delete</b><b>delete book.author; // Теперь объект book не имеет свойства author,</b><b>delete book["main title"]; // Теперь он не имеет свойства "main title".</b>Оператор
удаляет только собственные свойства и не удаляет унаследованные. (Чтобы удалить унаследованное свойство, необходимо удалять его в объекте-прототипе, в котором оно определено. Такая операция затронет все объекты, наследующие этот прототип.)<b>delete</b>Выражение
возвращает значение<b>delete</b>в случае успешного удаления свойства или когда операция удаления не привела к изменению объекта (например, при попытке удалить несуществующее свойство). Выражение<b>true</b>также возвращает<b>delete</b>, когда этому оператору передается выражение, не являющееся выражением обращения к свойству:<b>true</b><b>о = {х:1}; //о имеет собственное свойство х и наследует toString</b><b>delete о.х; // Удалит х и вернет true</b><b>delete о.х; // Ничего не сделает (х не существует) и вернет true</b><b>delete о.toString; // Ничего не сделает (toString не собственное свойство) и вернет true</b><b>delete 1; // Бессмысленно, но вернет true</b>Оператор
не удаляет ненастраиваемые свойства, атрибут<b>delete</b>которых имеет значение<b>configurable</b>. (Однако он может удалять настраиваемые свойства нерасширяемых объектов.) Ненастраиваемыми являются свойства встроенных объектов, а также свойства глобального объекта, созданные с помощью инструкций объявления переменных и функций. Попытка удалить ненастраиваемое свойство в строгом режиме вызывает исключение<b>false</b>. В нестрогом режиме (и в реализациях ECMAScript 3) в таких случаях оператор<b>Type Error</b>просто возвращает<b>delete</b>:<b>false</b><b>delete Object.prototype; // Удаление невозможно - ненастраиваемое свойство</b><b>var х = 1; // Объявление глобальной переменной</b><b>delete this.x; // Это свойство нельзя удалить</b><b>function f() {} // Объявление глобальной функции</b>