Дескриптор атрибутов - это новая концепция, добавленная в ES5, и его функция состоит в том, чтобы добавить больше управления свойствам объекта.
Object.DefineProperty
Чтобы изучить дескрипторы атрибутов, мы должны сначала рассказать о методе Object.DefineProperty. Цель этого метода - определить новые свойства для объекта или изменить существующие свойства. Прототип выглядит следующим образом:
Кода -копия выглядит следующим образом:
Object.DefineProperty (OBJ, PROP, Descriptor)
Пример использования:
Кода -копия выглядит следующим образом:
var obj = {};
Object.DefineProperty (obj, 'attr', {value: 1});
Приведенный выше код добавляет атрибут с именем ATTR в объект OBJ, со значением 1. Эквивалентно:
Кода -копия выглядит следующим образом:
var obj = {};
obj.attr = 1;
Для сравнения, написание Object.DefineProperty кажется более сложным. Тем не менее, его самый большой секрет заключается в третьем параметре.
Дескриптор данных
Предполагая, что мы хотим, чтобы ATRT был атрибутом только для чтения, мы можем добавить дескриптор данных с учетом данных:
Кода -копия выглядит следующим образом:
var obj = {};
Object.DefineProperty (obj, 'attr', {
значение: 1,
Записывается: ложь
});
console.log (obj.attr);
obj.attr = 2; // неудача
console.log (obj.attr);
Выполните вышеупомянутую программу, и вы обнаружите, что значение ATTR, распечатанное дважды, составляет 1, что означает, что написание атрибута не удалось. Тем не менее, этот результат будет немного необъяснимым, поскольку выполнение оператора назначения не имеет никаких исключений, но он не удается. Представьте себе, что если такая проблема возникнет в коде блокбастера, будет трудно устранить их. На самом деле, пока код запускается в строгом режиме, будет создано исключение:
Кода -копия выглядит следующим образом:
«Использовать строго»; // Введите строгий режим
var obj = {};
Object.DefineProperty (obj, 'attr', {
значение: 1,
Записывается: ложь
});
obj.attr = 2; // бросить исключение
Давайте посмотрим на другой перечисленный дескриптор данных, который может контролировать, можно ли перечислять атрибут. Если вы просто определите свойство, это свойство может быть перечислено в ... в цикле:
Кода -копия выглядит следующим образом:
var obj = {};
obj.attr = 1;
для (var i in obj) {console.log (obj [i]); }
Перечисляемое может «скрыть» это:
var obj = {};
Object.DefineProperty (obj, 'attr', {
значение: 1,
Перечисляемо: ложь
});
для (var i in obj) {console.log (obj [i]); }
Выполните приведенный выше код, и вы обнаружите, что консоль ничего не выпускает, потому что атрибут атрибута не может быть перечислен в настоящее время.
Сказав это, у вас может быть вопрос: может ли дескриптор атрибута быть изменен? Например, можно ли снова определить свойство только для чтения как записываемое? На самом деле, это зависит от другого настраиваемого дескриптора данных, который может контролировать, можно ли изменить дескриптор атрибута.
Кода -копия выглядит следующим образом:
var obj = {};
Object.DefineProperty (obj, 'attr', {
значение: 1,
Записывается: ложь,
настраивается: true
});
Object.DefineProperty (obj, 'attr', {
Записывается: правда
});
obj.attr = 2;
Приведенный выше код сначала определяет ATTR как атрибут только для чтения, а затем переопределяет его как записи. Таким образом, написание для ATTR успешно.
Доступ к дескриптору
Дескриптор доступа аналогичен аксессу Get/Set в объектно-ориентированном.
Кода -копия выглядит следующим образом:
var obj = {};
Object.DefineProperty (obj, 'attr', {
SET: function (val) {this._attr = math.max (0, val); },
get: function () {return this._attr; }
});
obj.attr = -1;
console.log (obj.attr); // 0
В приведенном выше коде доступ к ATTR действительно становится доступом к _ATTR, а минимальное значение ограничено 0 в функции SET.
Получить дескриптор атрибутов
Вышеупомянутые - это все настройки дескрипторов атрибутов, так как же получить определения сет? Object.getOwnPropertyDescriptor может сделать это.
Кода -копия выглядит следующим образом:
var obj = {};
Object.DefineProperty (obj, 'attr', {
значение: 1,
Записывается: ложь,
настраивается: true
});
var desc = object.getownpropertydescriptor (obj, 'attr');
console.dir (desc);
Объект управление
Object.DefineProperty, упомянутый ранее, работает на свойствах объекта, в то время как три метода, упомянутые ниже, работают непосредственно на объекте.
Object.preventextensions может помешать объектам иметь новые свойства:
Кода -копия выглядит следующим образом:
var obj = {};
obj.attr = 1;
Object.preventextensions (obj);
obj.attr2 = 2; //неудача
Object.Seal может сделать только значения свойств объекта, оставленные для изменения (если свойство только для чтения, даже значения свойства не могут быть изменены):
Кода -копия выглядит следующим образом:
var obj = {};
obj.attr = 1;
Object.Seal (obj);
obj.attr = 1,5;
Удалить obj.attr; // неудача
Object.Freeze может сделать объекты полностью неизменными:
Кода -копия выглядит следующим образом:
var obj = {};
obj.attr = 1;
Object.freeze (obj);
obj.attr = 1,5; // неудача
obj.attr2 = 2; //неудача
Затем вы можете спросить еще раз, как вы узнаете, был ли объект предотвратить, заморозить или заморозить? Ответ состоит в том, чтобы вызовать object.isextensible, Object.issealed и Object.isfrozen соответственно. Использование этих трех функций относительно просто и больше не громоздко.
В целом, объект может контролировать дескрипторы атрибутов, и строгость логики программы укрепляется. Единственным недостатком является то, что ES5 в основном реализован в IE9 (IE9 еще не поддерживает строгий режим). Учитывая, что внутренняя доля IE8 все еще относительно высока, этот набор вещей может использоваться только в мобильных браузерах и узле.