JavaScript. Подробное руководство, 6-е издание
Часть 73 из 535 Информация о книге
Пример 6.4. Функция
<b>classoff()</b><b>function classof(o) {</b><b> if (о === null) return "Null";</b><b> if (o === undefined) return "Undefined";</b><b> return Object.prototype.toString.call(o).slice(8,-1);</b><b>}</b>Этой функции classof() можно передать любое значение, допустимое в языке JavaScript. Числа, строки и логические значения действуют подобно объектам, когда относительно них вызывается метод
, а значения<b>toString()</b>и<b>null</b>обрабатываются особо. (В ECMAScript 5 особая обработка не требуется.) Объекты, созданные с помощью встроенных конструкторов, таких как<b>undefined</b>и<b>Array</b>, имеют атрибут<b>Date</b>, значение которого совпадает с именами их конструкторов. Объекты среды выполнения обычно также получают осмысленное значение атрибута<b>class</b>, однако это зависит от реализации. Объекты, созданные с помощью литералов или вызовом<b>class</b>, получают атрибут<b>Object.сreate</b>со значением «Object». Если вы определите свой конструктор, все объекты, созданные с его помощью, получат атрибут<b>class</b>со значением «Object»: нет никакого способа установить иное значение в атрибуте<b>class</b>для собственных классов объектов:<b>class</b><b>classof(null) // => "Null"</b><b>classof(1) // => "Number"</b><b>classof("") // => "String"</b><b>classof(false) // => "Boolean"</b><b>classof({}) // => "Object"</b><b>classof([]) // => "Array"</b><b>classof(/./) // => "Regexp"</b><b>classof(new DateO) // => "Date"</b><b>classof(window) // => "Window" (объект клиентской среды выполнения)</b><b>function f() {}; // Определение собственного конструктора</b><b>classof(new f()); // => "Object"</b>6.8.3. Атрибут extensible
Атрибут
объекта определяет, допускается ли добавлять в объект новые свойства. В ECMAScript 3 все встроенные и определяемые пользователем объекты неявно допускали возможность расширения, а расширяемость объектов среды выполнения определялась каждой конкретной реализацией. В ECMAScript 5 все встроенные и определяемые пользователем объекты являются расширяемыми, если они не были преобразованы в нерасширяемые объекты, а расширяемость объектов среды выполнения по-прежнему определяется каждой конкретной реализацией.<b>extensible</b>Стандарт ECMAScript 5 определяет функции для получения и изменения признака расширяемости объекта. Чтобы определить, допускается ли расширять объект, его следует передать методу
Чтобы сделать объект нерасширяемым, его нужно передать методу<b>Object.isExtensible().</b>. Обратите внимание, что после того как объект будет сделан нерасширяемым, его нельзя снова сделать расширяемым. Отметьте также, что вызов<b>Object.preventExtensions()</b>оказывает влияние только на расширяемость самого объекта. Если новые свойства добавить в прототип нерасширяемого объекта, нерасширяемый объект унаследует эти новые свойства.<b>preventExtensions()</b>Назначение атрибута
заключается в том, чтобы дать возможность «фиксировать» объекты в определенном состоянии, запретив внесение изменений. Атрибут объектов<b>extensible</b>часто используется совместно с атрибутами свойств<b>extensible</b>и<b>configurable</b>, поэтому в ECMAScript 5 определяются функции, упрощающие одновременную установку этих атрибутов.<b>writable</b>Метод
действует подобно методу<b>Object.seal()</b>, но он не только делает объект нерасширяемым, но и делает все свойства этого объекта недоступными для настройки. То есть в объект нельзя будет добавить новые свойства, а существующие свойства нельзя будет удалить или настроить. Однако существующие свойства, доступные для записи, по-прежнему могут быть изменены.<b>Object.preventExtensions()</b>После вызова
объект нельзя будет вернуть в прежнее состояние. Чтобы определить, вызывался ли метод<b>Object.seal()</b>для объекта, можно вызвать метод<b>Object.seal()</b><b>Object.isSealed().</b>Метод
обеспечивает еще более жесткую фиксацию объектов. Помимо того, что он делает объект нерасширяемым, а его свойства недоступными для настройки, он также делает все собственные свойства с данными доступными только для чтения. (Это не относится к свойствам объекта с методами доступа, обладающими методами записи; эти методы по-прежнему будут вызываться инструкциями присваивания.) Чтобы определить, вызывался ли метод<b>Object.freeze()</b>объекта, можно вызвать метод<b>Object.freeze()</b>.<b>Object.isFrozen()</b>Важно понимать, что
и<b>Object.seal()</b>воздействуют только на объект, который им передается: они не затрагивают прототип этого объекта. Если в программе потребуется полностью зафиксировать объект, вам, вероятно, потребуется зафиксировать также объекты в цепочке прототипов.<b>Object.freeze()</b>Все методы,
,<b>Object.preventExtensions()</b>и<b>Object.seal()</b>, возвращают переданный им объект, а это означает, что их можно использовать во вложенных вызовах:<b>Object.freeze()</b>