Введите ваш адрес почты


sdcvoy.ru
Понравился сайт? Поделись с друзьями!
Главная » Javascript » Deskriptory-gettery-i-settery-svojstv

Дескрипторы, геттеры и сеттеры свойств

дескриптор, get/setВ этом уроке мы рассмотрим возможности, которые способны управлять свойствами объекта. А управлять свойствами объекта мы будем с помощью специальных методов JavaScript. Основным из которых является  Object.defineProperty.

Дескриптор (descriptor)

Итак, давайте рассмотрим метод Object.defineProperty подробнее. Общий синтаксис использования имеет следующий вид:

Object.defineProperty(obj, prop, descriptor)

Аргументы:

В сам дескриптор могут входить следующие поля:


Запрещено одновременно указывать значение value и функций get/set. Также запрещено и не имеет смысла указывать writable при наличии get/set-функций.


Давайте попробуем с помощью дескриптора создать свойство-константу:

var acceleration = {}; 
Object.defineProperty( acceleration, "gravity", {
  value: 9.8,
  writable: false, // запретить присвоение "acceleration.gravity="
  configurable: false // запретить удаление "acceleration.gravity"
});
acceleration.gravity = 10; // пробуем изменить свойство объекта
delete acceleration.gravity; // пытаемся удалить acceleration.gravity
alert(acceleration.gravity); // выведет 9.8

Бывает так что нам не нужно перечислять некоторые свойства объекта. Для этого воспользуемся полем enumerable. А прятать мы будем метод toString, который также виден с помощью метода Object.keys():

var user = {
  login: "admin",
  password: "pass",
  toString: function() { return this.login; }
};

Object.defineProperty(user, "toString", {enumerable: false});

var arrKeys = Object.keys(user); // создаём массив из ключей объекта

alert( arrKeys ); // login, password

Попробуйте поменять значение поля enumerable на true, результат не заставит себя долго ждать.

Геттеры (get)

Функция get позволяет нам возвратить свойство объекта. Это бывает очень полезно когда вам нужно поменять свойство в объекте, а копаться в коде нет времени. Мы можем сделать это налету, даже не копаясь в коде. Гетерры позволяют задавать свойства, которые работают как функции:

var sphere={
x:1,
y:1,
z:1
}

Object.defineProperty( sphere, "radius", {
get:function(){
return Math.sqrt(Math.pow(this.x,2) + Math.pow(this.y,2) + Math.pow(this.z,2));
  }
});
alert( sphere.radius ); // 1.73205081

Если кто не догадался я задал свойство, которое действует как функция, вычисляющая радиус сферы.

Сеттеры (set)

Сеттеры позволяют записав значение свойства использовать его. Причем можно изменять другие свойства. Давайте с помощью сеттера попробуем решить обратную задачу, вычислив координаты сферы. Условия остаются те же самые, что и прежде:

var sphere={
x:1,
y:1,
z:1
}

Object.defineProperty( sphere, "radius", {
   get:function(){
return Math.sqrt(Math.pow(this.x,2) + Math.pow(this.y,2) + Math.pow(this.z,2));
  },
  set: function(value) {
      return this.x = this.y = this.z = Math.sqrt((Math.pow(value,2))/3)       
    }
});
sphere.radius = 10; // функция-сеттер возьмет значение отсюда
alert( sphere.x ); // 5.774
alert( sphere.y ); // 5.774
alert( sphere.z ); // 5.774

Хотел отметить, что get/set можно вызвать непосредственно в самом объекте, а не в методе, как мы делали это раньше:

var sphere={
x:1,
y:1,
z:1,
   get radius(){
return Math.sqrt(Math.pow(this.x,2) + Math.pow(this.y,2) + Math.pow(this.z,2));
  },
  set radius(value) {
      return this.x = this.y = this.z = Math.sqrt((Math.pow(value,2))/3)       
    }
};
alert( sphere.radius ); // ввыведет значение из геттера (1.1.73205081)
sphere.radius = 10;
alert( sphere.x ); // 5.774
alert( sphere.y ); // 5.774
alert( sphere.z ); // 5.774  

Существуют и другие методы для работы со свойствами объектов. Хотелось бы отметить два из них: Object.defineProperties(obj, descriptors) и Object.getOwnPropertyDescriptor(obj, prop)

Метод Object.defineProperties(obj, descriptors) позволяет работать сразу с несколькими свойствами объекта:


var user = {}

Object.defineProperties(user, {
  login: {
    value: "nightgremlin",
    
  },

  password: {
    value: "pass"
  },

  fullData: {
    get: function() {
      return 'Логин: ' + this.login + '\n' + 'Пароль: ' + this.password;
    }
  }
});

alert( user.fullData ); // Логин: nightgremlin Пароль: pass

По сути этот метод даёт больше возможностей, чем предыдущий. А вот благодаря следующему методу мы можем получить доступ к дескриптору:

var acceleration = {
gravity:9.8
}; 

var descriptor = Object.getOwnPropertyDescriptor(acceleration, "gravity");
descriptor.writable = false; 
descriptor.configurable = false; 

Object.defineProperty( acceleration, "gravity", descriptor );
acceleration.gravity = 10; // пробуем изменить свойство объекта

delete acceleration.gravity; // пытаемся удалить acceleration.gravity

alert(acceleration.gravity); // выведет 9.8

Что произошло? Просто мы изменили сам дескриптор. Работу данного скрипта можно посмотреть здесь: Object.getOwnPropertyDescriptor(obj, prop).


Остальные методы используются довольно редко, поэтому не будем заострять на них внимание. Надеюсь вам понравился урок, но дальше будет ещё интереснее, так что, чтобы не пропустить свежие уроки подписывайтесь на рассылку.



наверх