• Если свойство с методами доступа недоступно для настройки, нельзя изменить его методы чтения и записи и нельзя превратить его в простое свойство с данными.
• Если свойство с данными недоступно для настройки, нельзя превратить его в свойство с методами доступа.
• Если свойство с данными недоступно для настройки, нельзя изменить значение его атрибута writable
с false
на true
, но его можно Изменить с true
на false
.
• Если свойство с данными недоступно для настройки и для записи, нельзя изменить его значение. Однако изменить значение свойства, недоступного для записи можно, если оно доступно для настройки (потому что свойство можно сделать доступным для записи, изменить его значение и затем опять сделать свойство доступным только для чтения).
Пример 6.2 включает функцию extend(),
которая копирует свойства из одного объекта в другой. Эта функция просто копирует имена и значения свойств и игнорирует их атрибуты. Кроме того, она не копирует методы чтения и записи из свойств с методами доступа, а просто преобразует их в свойства со статическими данными. В примере 6.3 показана новая версия extend(),
которая копирует все атрибуты свойств с помощью Object.getOwnPropertyDescriptor()
и Object.defineProperty().
Но на этот раз данная версия оформлена не как функция, а как новый метод объекта и добавляется в Object.prototype
как свойство, недоступное для перечисления.
Пример 6.3. Копирование атрибутов свойств
/*
* Добавляет неперечислимый метод extend() в Object.prototype.
* Этот метод расширяет объекты возможностью копирования свойств из объекта,
* переданного в аргументе. Этот метод копирует не только значение свойств,
* но и все их атрибуты. Из объекта в аргументе копируются все собственные
* свойства (даже недоступные для перечисления), за исключением одноименных
* свойств, имеющихся в текущем объекте.
*/
Object.defineProperty(Object.prototype,
"extend", // Определяется Object.prototype.extend
{
writable: true,
enumerable: false, // Сделать неперечислимым
configurable: true,
value: function(o) { // Значением свойства является данная функция
// Получить все собственные свойства, даже неперечислимые
var names = Object.getOwnPropertyNames(o);
// Обойти их в цикле
for(var і = 0: і < names.length; i++) {
// Пропустить свойства, уже имеющиеся в данном объекте
if (names[i] in this) continue;
// Получить дескриптор свойства из о
var desc = Object.getOwnPropertyDescriptor(o,names[i]);
// Создать с его помощью свойство в данном объекте
Object.defineProperty(this, names[i], desc);
}
}
});
6.7.1. Устаревшие приемы работы с методами чтения и записи
Синтаксис определения свойств с методами доступа в литералах объектов, описанный разделе 6.6, позволяет определять свойства с методами в новых объектах, но, он не дает возможности получать методы чтения и записи и добавлять новые свойства с методами доступа к существующим объектам. В ECMAScript 5 для этих целей можно использовать Object.getOwnPropertyDescriptor()
и Object.defineProperty()
.
Большинство реализаций JavaScript (за исключением веб-броузера IE) поддерживали синтаксис get
и set
в литералах объектов еще до принятия стандарта ECMAScript 5. Эти реализации поддерживают нестандартный, устаревший API для получения и назначения методов чтения и записи. Этот API состоит из четырех методов, доступных во всех объектах. __lookupGetter__()
и __lookupSetter__()
возвращают методы чтения и записи для указанного свойства. А методы __defineGetter__()
и __defineSetter__()
позволяют определить метод чтения или записи:
в первом аргументе они принимают имя свойства, а во втором - метод чтения или записи. Имена всех этих методов начинаются и оканчиваются двумя символами подчеркивания, чтобы показать, что они являются нестандартными методами. Эти нестандартные методы не описываются в справочном разделе.
Читать дальше
Конец ознакомительного отрывка
Купить книгу