JavaScript. Подробное руководство, 6-е издание
Методы получения и записи значений атрибутов свойств, предусмотренные стандартом ECMAScript 5, используют объект, называемый дескриптором свойства (
), представляющий множество из четырех атрибутов. Объект дескриптора свойства обладает свойствами, имена которых совпадают с именами атрибутов свойства, которое он описывает. То есть объекты-дескрипторы свойств с данными имеют свойства с именами<b>property descriptor</b>,<b>value</b>,<b>writable</b>и<b>enumerable</b>. А дескрипторы свойств с методами доступа вместо свойств<b>configurable</b>и<b>value</b>имеют свойства<b>writable</b>и<b>get</b>. Свойства<b>set</b>,<b>writable</b>и<b>enumerable</b>являются логическими значениями, а свойства<b>configurable</b>и<b>get</b>- функциями.<b>set</b>Получить дескриптор свойства требуемого объекта можно вызовом
<b>Object.get-OwnPropertyDescriptor():</b><b>// Вернет {value: 1, writable:true, enumerable:true, configurable:true}</b><b>Object.getOwnPropertyDescriptor({x:1}, "x");</b><b>// Теперь получим свойство octet объекта random, объявленного выше.</b><b>// Вернет { get: /*func*/. set:undefined, enumerable:true, configurable:true}</b><b>Object.getOwnPropertyDescriptor(random, "octet");</b><b>// Вернет undefined для унаследованных и несуществующих свойств. </b><b>Object.getOwnPropertyDescriptor({}, "х"); // undefined, нет такого свойства</b><b>Object.getOwnPropertyDescriptor({}, "toString"); // undefined, унаследованное</b>Как можно заключить из названия метода,
работает только с собственными свойствами. Чтобы получить атрибуты унаследованного свойства, необходимо явно выполнить обход цепочки прототипов (смотрите описание<b>Object.getOwnPropertyDescriptor()</b>в разделе 6.8.1).<b>Object.getPrototypeOf()</b>Чтобы изменить значение атрибута свойства или создать новое свойство с заданными значениями атрибутов, следует вызвать метод
, передав ему объект, в котором требуется выполнить изменения, имя создаваемого или изменяемого свойства и объект дескриптора свойства:<b>Object.defineProperty()</b><b>var о = {}; // Создать пустой объект без свойств</b><b>// Создать неперечислимое простое свойство х со значением 1.</b><b>Object.defineProperty(o, "х", { value : 1,</b><b> writable: true, enumerable: false, configurable: true}):</b><b>// Убедиться, что свойство создано и является неперечислимым </b><b>о.х; // => 1</b><b>Object.keys(o) // => []</b><b>// Теперь сделать свойство х доступным только для чтения </b><b>Object.defineProperty(o, "х", { writable: false });</b><b>// Попытаться изменить значение свойства</b><b>о.х = 2; // Неудача, в строгом режиме возбудит ТуреЕrror</b>Дескриптор свойства, передаваемый методу
необязательно должен иметь все четыре атрибута. При создании нового свойства отсутствующие атрибуты получат значение<b>Object.defineProperty(),</b>или<b>false</b>. При изменении существующего свойства для отсутствующих атрибутов будут сохранены текущие значения. Обратите внимание, что этот метод изменяет существующее собственное свойство или создает новое собственное свойство - он не изменяет унаследованные свойства.<b>undefined</b>Если возникнет необходимость создать или изменить сразу несколько свойств, можно воспользоваться методом
Первым аргументом ему передается объект, который требуется изменить. Вторым аргументом - объект, отображающий имена создаваемых или модифицируемых свойств в дескрипторы этих свойств. Например:<b>Object.defineProperties().</b><b>var р = Object.defineProperties({},{</b><b> х:{ </b><b> value: 1, </b><b> writable: true,</b><b> enumerable:true, </b><b> configurable:true </b><b> }, </b><b> y:{ </b><b> value: 1,</b><b> writable: true,</b><b> enumerable:true,</b><b> configurable:true },</b><b> r:{</b><b> get: function() { return Math.sqrt(this.x*this.x + this.y*this.y) },</b><b> enumerable:true,</b><b> configurable:true</b><b> }</b><b>});</b>В этом примере все начинается с пустого объекта, в который затем добавляются два свойства с данными и одно свойство с методами доступа, доступное только для чтения. Он опирается на тот факт, что
возвращает модифицированный объект (подобно методу<b>Object.defineProperties()</b>).<b>Object.defineProperty()</b>