Книга: Выразительный JavaScript
Геттеры и сеттеры
Геттеры и сеттеры
При создании интерфейса можно ввести свойства, не являющиеся методами. Мы могли бы определить minHeight
и minWidth
как переменные для хранения чисел. Но это потребовало бы от нас написать код вычисления их значений в конструкторе, что плохо, поскольку эти операции не связаны напрямую с конструированием объекта. Это может аукнуться, когда, например, внутренняя ячейка подчёркнутой ячейки изменяется – в этот момент размер подчеркивания тоже должен измениться.
Эти соображения привели к тому, что свойства, не являющиеся методами, многие не включают в интерфейс. Вместо прямого доступа к свойствам-значениям, используются методы типа getSomething
и setSomething
для чтения и записи значений свойств. Но в таком подходе есть и минус – приходится писать (и читать) много дополнительных методов.
К счастью, JavaScript даёт нам технику, использующую лучшее из обоих подходов. Мы можем задать свойства, которые снаружи выглядят обыкновенными, но втайне имеют связанные с ними методы.
var pile = {
elements: ["скорлупа", "кожура", "червяк"],
get height() {
return this.elements.length;
},
set height(value) {
console.log("Игнорируем попытку задать высоту", value);
}
};
console.log(pile.height);
// ? 3
pile.height = 100;
// ? Игнорируем попытку задать высоту 100
В объявлении объекта записи get
или set
позволяют задать функцию, которая будет вызвана при чтении или записи свойства. Можно также добавить такое свойство в существующий объект, к примеру, в prototype
, используя функцию Object.defineProperty
(раньше мы её уже использовали, создавая несчётные свойства).
Object.defineProperty(TextCell.prototype, "heightProp", {
get: function() { return this.text.length; }
});
var cell = new TextCell("даnну");
console.log(cell.heightProp);
// ? 2
cell.heightProp = 100;
console.log(cell.heightProp);
// ? 2
Так же можно задавать свойство set
в объекте, передаваемом в defineProperty
, для задания метода-сеттера. Когда геттер есть, а сеттера нет, попытка записи в свойство просто игнорируется.