JavaScript. Подробное руководство, 6-е издание, стр. 65

<b>var len = book &amp;&amp; book.subtitle &amp;&amp; book.subtitle.length;</b>

Чтобы понять, почему второе выражение позволяет предотвратить появление исключений

<b>ТуреЕrror</b>
, можете вернуться к описанию короткой схемы вычислений, используемой оператором
<b>&amp;&amp;</b>
, в разделе 4.10.1. Разумеется, попытка установить значение свойства для значения
<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>
с методами доступа и атрибут
<b>extensible</b>
(раздел 6.8.3) объекта
<b>о</b>
имеет значение
<b>false</b>
. Если свойство
<b>р</b>
отсутствует в объекте
<b>о</b>
и для него не определен метод записи, то операция присваивания попытается добавить свойство
<b>р</b>
в объект
<b>о</b>
. Но поскольку объект
<b>о</b>
не допускает возможность расширения, то попытка добавить в него новое свойство потерпит неудачу.

6.3. Удаление свойств

Оператор

<b>delete</b>
(раздел 4.13.3) удаляет свойство из объекта. Его единственный операнд должен быть выражением обращения к свойству. Может показаться удивительным, но оператор
<b>delete</b>
не оказывает влияния на значение свойства - он оперирует самим свойством:

<b>delete book.author; // Теперь объект book не имеет свойства author,</b>

<b>delete book[&quot;main title&quot;]; // Теперь он не имеет свойства &quot;main title&quot;.</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>
. (Однако он может удалять настраиваемые свойства нерасширяемых объектов.) Ненастраиваемыми являются свойства встроенных объектов, а также свойства глобального объекта, созданные с помощью инструкций объявления переменных и функций. Попытка удалить ненастраиваемое свойство в строгом режиме вызывает исключение
<b>Type Error</b>
. В нестрогом режиме (и в реализациях ECMAScript 3) в таких случаях оператор
<b>delete</b>
просто возвращает
<b>false</b>
:

<b>delete Object.prototype; // Удаление невозможно - ненастраиваемое свойство</b>

<b>var х = 1; // Объявление глобальной переменной</b>

<b>delete this.x; // Это свойство нельзя удалить</b>

<b>function f() {} // Объявление глобальной функции</b>