Указание get/set в литералах
Если мы создаём объект при помощи синтаксиса { ... } , то задать свойства‑функции можно прямо в его определении. Для этого используется особый синтаксис: get свойство или set свойство .
Например, ниже объявлен геттер‑сеттер fullName :
var user = { firstName: "Вася", surname: "Петров",
get fullName() {
return this.firstName + ' ' + this.surname;
},
set fullName(value) {
var split = value.split(' '); this.firstName = split[0]; this.surname = split[1];
}
};
alert( user.fullName ); // Вася Петров (из геттера) user.fullName = "Петя Иванов";
alert( user.firstName ); // Петя (поставил сеттер) alert( user.surname ); // Иванов (поставил сеттер)
Да здравствуют get/set!
Казалось бы, зачем нам назначать get/set для свойства через всякие хитрые вызовы, когда можно сделать просто функции с самого начала? Например,
getFullName , setFullName …
Конечно, в ряде случаев свойства выглядят короче, такое решение просто может быть красивым. Но основной бонус – это гибкость, возможность получить контроль над свойством в любой момент!
Например, в начале разработки мы используем обычные свойства, например у User будет имя name и возраст age :
function User(name, age) { this.name = name; this.age = age;
}
var pete = new User("Петя", 25); alert( pete.age ); // 25
С обычными свойствами в коде меньше букв, они удобны, причины использовать функции пока нет.
…Но рано или поздно могут произойти изменения. Например, в User может стать более целесообразно вместо возраста age хранить дату рождения
birthday :
function User(name, birthday) { this.name = name; this.birthday = birthday;
}
var pete = new User("Петя", new Date(1987, 6, 1));
Что теперь делать со старым кодом, который выводит свойство age ?
Можно, конечно, найти все места и поправить их, но это долго, а иногда и невозможно, скажем, если вы взаимодействуете со сторонней библиотекой, код в которой – чужой и влезать в него нежелательно.
Добавление get ‑функции age позволяет обойти проблему легко и непринуждённо:
function User(name, birthday) { this.name = name; this.birthday = birthday;
// age будет высчитывать возраст по birthday Object.defineProperty(this, "age", {
get: function() {
var todayYear = new Date().getFullYear(); return todayYear ‐ this.birthday.getFullYear();
}
});
}
var pete = new User("Петя", new Date(1987, 6, 1));
alert( pete.birthday ); // и дата рождения доступна alert( pete.age ); // и возраст
Заметим, что pete.age снаружи как было свойством, так и осталось. То есть, переписывать внешний код на вызов функции pete.age() не нужно.
Таким образом, defineProperty позволяет нам начать с обычных свойств, а в будущем, при необходимости, можно в любой момент заменить их на функции, реализующие более сложную логику.
Do'stlaringiz bilan baham: |