Меню

Геттеры и сеттеры в javascript

17.05.2018 - java script, ЯП

Getters and Setters

В прошлый раз мы переделывали методы в приватные методы.

function Circle(radius) {
  let defaultLocation = { x: 0, y: 0 };

  this.draw = function() {
    console.log("draw");
  };
}

Но если быть более точным, они не являются приватными методами объекта circle, так как технически их нету внутри этого объекта. Они являются локальными переменными, которые мы определили внутри функции Circle, но с точки зрения ООП, мы можем обращаться к ним как к частным (private) членам объекта circle.

Вот у нас есть private свойство defaultLocation и мы не можем обратиться к нему извне. Но что если мы хотим отобразить его где-нибудь в нашем приложении. Мы не хотим изменять его, мы просто хотим его прочитать. Итак, одно из решений — это определить функцию, например getDefaultLocation и вернуть из нее значение требуемого свойства.

function Circle(radius) {
  let defaultLocation = { x: 0, y: 0 };

  this.getDefaultLocation = function() {
    return defaultLocation;
  };
  this.draw = function() {
    console.log("draw");
  };
}

let circle = new Circle(100);

Затем мы можем обратиться к этому методу, там где нам нужно

circle.getDefaultLocation();

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

Вот как мы можем это реализовать:

Воспользуемся встроенным объектом Object, а точнее его свойством defineProperty. Так же у него есть свойство defineProperties, если мы захотим установить сразу несколько пропертей.

Первым аргументом этого метода идёт объект, куда мы хотим захерачить новые проперти.

В нашем случае это объект, на который указывает this. Например объект circle.

Вторым аргументом является название проперти, которую мы хотим добавить. Например, назовём её defaultLocation.

Третий аргумент — это объект. В этот объект мы добавим пару key - value. Ключом будет get — это специальный ключ в js и в роли value — функция. И эта функция будет вызвана, когда мы вызовем circle.defaultLocation.

Object.defineProperty(this, "defaultLocation", {
  get: function() {
    return defaultLocation;
  }
});

Еще раз, переменная defaultLocation является частью замыкания этой внутренней функции get, поэтому у нас есть доступ к ней.

Если мы вызовем наш объект в devtools, то мы увидим, что в нём есть параметр defaultLocation и getter — get defaultLocation.

getter

Getter — это функция которая используется для чтения свойства. Итак, эта проперть defaultLocation, мы обращаемся к ней как к readOnly свойству.

Теперь, если мы захотим установить значение этой проперти извне, то мы определим setter. Итак, в нашем объекте мы добавим еще одну пару key - value. Ключ set — также является специальным ключевым словаом. И в роли value также указываем функцию. Эта функция принимает аргумент, такой как value. Что самое интересное, так как это функция, мы можем организовать нейкую предобработку данных перед тем, как установим значение в наш defaultLocation. Например, сделаем простенький валидатор:

Если value.x и value.y равны false, то мы можем кинуть ошибку, созданную с помощью встроенного конструктора Error, для создания объектов ошибок.

Object.defineProperty(this, "defaultLocation", {
  get: function() {
    return defaultLocation;
  },
  set: function(value) {
    if (!value.x || !value.y) {
      throw new Error("Invalid location");
    }
    defaultLocation = value;
  }
});

Вот такие плюсы у setter.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *