Код
const user = {
name: 'Alex',
surname: 'Smith',
birthday: '20/04/1993',
showMyPublicData: function() {
console.log(`${this.name} ${this.surname}`);
}
}
У каждого из свойств объекта помимо значения есть специальные атрибуты (флаги).
writable - если установлено в
true, то это свойство объекта можно будет изменить, если
false - только для чтения
enumerable - если установлено в
true, то это свойство будет перечисляться в циклах, если
false - будет игнорироваться
configurable - если установлено в
true, то свойство можно будет удалить, а его атрибуты можно изменять, иначе сделать этого будет нельзя
По умолчанию для всех создаваемых свойств объекта, флаги стоят в позиции
true.
Выведем в консоль флаги свойства
name Код
console.log(Object.getOwnPropertyDescriptor(user, 'name'));
Цитата
Object
configurable: true
enumerable: true
value: "Alex"
writable: true
[[Prototype]]: Object
Изменим значение флагов этого свойства:
Код
Object.defineProperty(user, 'name', {writable: false});
Мы изменили возможность редактирования данного свойства, пробуем перезаписать его значение:
И получаем ошибку, так как наше свойство теперь стало только для чтения (
read only):
Цитата
Uncaught TypeError: Cannot assign to read only property 'name' of object
При помощи
defineProperty можно создавать новые свойства, с заданными параметрами флагов, причем свойства, которых еще нет в данном объекте. Если при этом не устанавливать значения флагов, то они по умолчанию станут
false.
Например:
Код
Object.defineProperty(user, 'gender', {value: 'male'});
Выведем в консоль флаги созданного нового свойства
Код
console.log(Object.getOwnPropertyDescriptor(user, 'gender'));
Цитата
{
value: 'male',
writable: false,
enumerable: false,
configurable: false
}
Практическое применение: допустим, стоит задача, что когда пользователь заполняет анкету, дату рождения он может указать только один раз, без возможности её дальнейшего редактирования.
Код
Object.defineProperty(user, 'birthday', {writable: false});
Можно вообще сделать это в динамике, изначально убрав из объекта свойство
birthday, а потом добавлять его, получая значение от пользователя и при этом сразу установить нужные флаги:
Код
Object.defineProperty(user, 'birthday', {value: prompt('Введите дату рождения'), enumerable: true, configurable: true});
Выведем в консоль флаги свойства
birthday Код
console.log(Object.getOwnPropertyDescriptor(user, 'birthday'));
Цитата
{value: '02.12.1974', writable: false, enumerable: true, configurable: true}
Пример 2: допустим, нам нужно куда-то выводить данные из этого объекта. При этом данные нужны только имя, фамилия, дата рождения. Но в объекте также есть и метод, который также пойдёт в работу.
Как сделать так, чтобы при переборе не было видно метода?
Установить ему нужный флаг:
Код
Object.defineProperty(user, 'showMyPublicData', {enumerable: false});
for (let key in user) console.log(key);
Можно редактировать сразу несколько свойств с помощью метода
Object.defineProperties Код
Object.defineProperties(user, {
name: {writable: false},
surname: {writable: false}
});
Полезные методы объектов
Метод Object.keys() возвращает массив из собственных перечисляемых свойств переданного объекта, в том же порядке, в котором они бы обходились циклом
for...in Код
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.keys(obj)); // ['0', '1', '2']
Метод Object.values() возвращает массив значений перечисляемых свойств объекта в том же порядке что и цикл
for...in.
Код
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.values(obj)); // ['a', 'b', 'c']
Object.entries() метод возвращает массив собственных перечисляемых свойств указанного объекта в формате
[key, value], в том же порядке, что и в цикле
for...in Код
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
Всего комментариев: 0