ÐÑÑÑ Ð´Ð²Ð° Ñипа ÑвойÑÑв обÑекÑа.
ÐеÑвÑй Ñип ÑÑо ÑвойÑÑва-даннÑе (data properties). ÐÑ Ñже знаем, как ÑабоÑаÑÑ Ñ Ð½Ð¸Ð¼Ð¸. ÐÑе ÑвойÑÑва, коÑоÑÑе Ð¼Ñ Ð¸ÑполÑзовали до ÑекÑÑего моменÑа, бÑли ÑвойÑÑвами-даннÑми.
ÐÑоÑой Ñип ÑвойÑÑв Ð¼Ñ ÐµÑÑ Ð½Ðµ ÑаÑÑмаÑÑивали. ÐÑо ÑвойÑÑва-акÑеÑÑоÑÑ (accessor properties). Ðо Ñвоей ÑÑÑи ÑÑо ÑÑнкÑии, коÑоÑÑе иÑполÑзÑÑÑÑÑ Ð´Ð»Ñ Ð¿ÑиÑÐ²Ð¾ÐµÐ½Ð¸Ñ Ð¸ полÑÑÐµÐ½Ð¸Ñ Ð·Ð½Ð°ÑениÑ, но во внеÑнем коде они вÑглÑдÑÑ ÐºÐ°Ðº обÑÑнÑе ÑвойÑÑва обÑекÑа.
ÐеÑÑеÑÑ Ð¸ ÑеÑÑеÑÑ
СвойÑÑва-акÑеÑÑоÑÑ Ð¿ÑедÑÑÐ°Ð²Ð»ÐµÐ½Ñ Ð¼ÐµÑодами: «геÑÑеÑ» â Ð´Ð»Ñ ÑÑÐµÐ½Ð¸Ñ Ð¸ «ÑеÑÑеÑ» â Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи. ÐÑи лиÑеÑалÑном обÑÑвлении обÑекÑа они обознаÑаÑÑÑÑ get и set:
let obj = {
get propName() {
// геÑÑеÑ, ÑÑабаÑÑÐ²Ð°ÐµÑ Ð¿Ñи ÑÑении obj.propName
},
set propName(value) {
// ÑеÑÑеÑ, ÑÑабаÑÑÐ²Ð°ÐµÑ Ð¿Ñи запиÑи obj.propName = value
}
};
ÐеÑÑÐµÑ ÑÑабаÑÑваеÑ, когда obj.propName ÑиÑаеÑÑÑ, ÑеÑÑÐµÑ â когда знаÑение пÑиÑваиваеÑÑÑ.
ÐапÑимеÑ, Ñ Ð½Ð°Ñ ÐµÑÑÑ Ð¾Ð±ÑÐµÐºÑ user Ñо ÑвойÑÑвами name и surname:
let user = {
name: "John",
surname: "Smith"
};
Ð ÑепеÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸Ð¼ ÑвойÑÑво обÑекÑа fullName Ð´Ð»Ñ Ð¿Ð¾Ð»Ð½Ð¾Ð³Ð¾ имени, коÑоÑое в наÑем ÑлÑÑае "John Smith". Само Ñобой, Ð¼Ñ Ð½Ðµ Ñ
оÑим дÑблиÑоваÑÑ Ñже имеÑÑÑÑÑÑ Ð¸Ð½ÑоÑмаÑиÑ, Ñак ÑÑо ÑеализÑем его пÑи помоÑи акÑеÑÑоÑа:
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
}
};
alert(user.fullName); // John Smith
СнаÑÑжи ÑвойÑÑво-акÑеÑÑÐ¾Ñ Ð²ÑглÑÐ´Ð¸Ñ ÐºÐ°Ðº обÑÑное ÑвойÑÑво. Ð ÑÑом и заклÑÑаеÑÑÑ ÑмÑÑл ÑвойÑÑв-акÑеÑÑоÑов. ÐÑ Ð½Ðµ вÑзÑваем user.fullName как ÑÑнкÑиÑ, а ÑиÑаем как обÑÑное ÑвойÑÑво: геÑÑÐµÑ Ð²ÑÐ¿Ð¾Ð»Ð½Ð¸Ñ Ð²ÑÑ ÑабоÑÑ Ð·Ð° кÑлиÑами.
Ðа даннÑй Ð¼Ð¾Ð¼ÐµÐ½Ñ Ñ fullName еÑÑÑ ÑолÑко геÑÑеÑ. ÐÑли Ð¼Ñ Ð¿Ð¾Ð¿ÑÑаемÑÑ Ð½Ð°Ð·Ð½Ð°ÑиÑÑ user.fullName=, пÑоизойдÑÑ Ð¾Ñибка:
let user = {
get fullName() {
return `...`;
}
};
user.fullName = "ТеÑÑ"; // ÐÑибка (Ñ ÑвойÑÑва еÑÑÑ ÑолÑко геÑÑеÑ)
ÐавайÑе иÑпÑавим ÑÑо, добавив ÑеÑÑÐµÑ Ð´Ð»Ñ user.fullName:
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
},
set fullName(value) {
[this.name, this.surname] = value.split(" ");
}
};
// set fullName запÑÑÑиÑÑÑ Ñ Ð´Ð°Ð½Ð½Ñм знаÑением
user.fullName = "Alice Cooper";
alert(user.name); // Alice
alert(user.surname); // Cooper
РиÑоге Ð¼Ñ Ð¿Ð¾Ð»ÑÑили «виÑÑÑалÑное» ÑвойÑÑво fullName. Ðго можно пÑоÑиÑаÑÑ Ð¸ измениÑÑ.
ÐеÑкÑипÑоÑÑ ÑвойÑÑв доÑÑÑпа
ÐеÑкÑипÑоÑÑ ÑвойÑÑв-акÑеÑÑоÑов оÑлиÑаÑÑÑÑ Ð¾Ñ Â«Ð¾Ð±ÑÑнÑÑ Â» ÑвойÑÑв-даннÑÑ .
СвойÑÑва-акÑеÑÑоÑÑ Ð½Ðµ имеÑÑ value и writable, но взамен пÑедлагаÑÑ ÑÑнкÑии get и set.
То еÑÑÑ, деÑкÑипÑÐ¾Ñ Ð°ÐºÑеÑÑоÑа Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ:
getâ ÑÑнкÑÐ¸Ñ Ð±ÐµÐ· аÑгÑменÑов, коÑоÑÐ°Ñ ÑÑабоÑÐ°ÐµÑ Ð¿Ñи ÑÑении ÑвойÑÑва,setâ ÑÑнкÑиÑ, пÑинимаÑÑÐ°Ñ Ð¾Ð´Ð¸Ð½ аÑгÑменÑ, вÑзÑÐ²Ð°ÐµÐ¼Ð°Ñ Ð¿Ñи пÑиÑвоении ÑвойÑÑва,enumerableâ Ñо же Ñамое, ÑÑо и Ð´Ð»Ñ ÑвойÑÑв-даннÑÑ ,configurableâ Ñо же Ñамое, ÑÑо и Ð´Ð»Ñ ÑвойÑÑв-даннÑÑ .
ÐапÑимеÑ, Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð°ÐºÑеÑÑоÑа fullName пÑи помоÑи defineProperty Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ пеÑедаÑÑ Ð´ÐµÑкÑипÑÐ¾Ñ Ñ Ð¸ÑполÑзованием get и set:
let user = {
name: "John",
surname: "Smith"
};
Object.defineProperty(user, 'fullName', {
get() {
return `${this.name} ${this.surname}`;
},
set(value) {
[this.name, this.surname] = value.split(" ");
}
});
alert(user.fullName); // John Smith
for(let key in user) alert(key); // name, surname
ÐÑÑ Ñаз замеÑим, ÑÑо ÑвойÑÑво обÑекÑа Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð»Ð¸Ð±Ð¾ ÑвойÑÑвом-акÑеÑÑоÑом (Ñ Ð¼ÐµÑодами get/set), либо ÑвойÑÑвом-даннÑм (Ñо знаÑением value).
ÐÑи попÑÑке ÑказаÑÑ Ð¸ get, и value в одном деÑкÑипÑоÑе бÑÐ´ÐµÑ Ð¾Ñибка:
// Error: Invalid property descriptor.
Object.defineProperty({}, 'prop', {
get() {
return 1
},
value: 2
});
УмнÑе геÑÑеÑÑ/ÑеÑÑеÑÑ
ÐеÑÑеÑÑ/ÑеÑÑеÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ ÐºÐ°Ðº обÑÑÑки над «ÑеалÑнÑми» знаÑениÑми ÑвойÑÑв, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð±Ð¾Ð»ÑÑе конÑÑÐ¾Ð»Ñ Ð½Ð°Ð´ опеÑаÑиÑми Ñ Ð½Ð¸Ð¼Ð¸.
ÐапÑимеÑ, еÑли Ð¼Ñ Ñ
оÑим запÑеÑиÑÑ ÑÑÑанавливаÑÑ ÐºÐ¾ÑоÑкое Ð¸Ð¼Ñ Ð´Ð»Ñ user, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ ÑеÑÑÐµÑ name Ð´Ð»Ñ Ð¿ÑовеÑки, а Ñамо знаÑение Ñ
ÑаниÑÑ Ð² оÑделÑном ÑвойÑÑве _name:
let user = {
get name() {
return this._name;
},
set name(value) {
if (value.length < 4) {
alert("ÐÐ¼Ñ ÑлиÑком коÑоÑкое, должно бÑÑÑ Ð±Ð¾Ð»ÐµÐµ 4 Ñимволов");
return;
}
this._name = value;
}
};
user.name = "Pete";
alert(user.name); // Pete
user.name = ""; // ÐÐ¼Ñ ÑлиÑком коÑоÑкое...
Таким обÑазом, Ñамо Ð¸Ð¼Ñ Ñ
ÑаниÑÑÑ Ð² _name, доÑÑÑп к коÑоÑÐ¾Ð¼Ñ Ð¿ÑоизводиÑÑÑ ÑеÑез геÑÑÐµÑ Ð¸ ÑеÑÑеÑ.
ТеÑ
ниÑеÑки, внеÑний код вÑÑ ÐµÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð´Ð¾ÑÑÑп к имени напÑÑмÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ user._name, но ÑÑÑеÑÑвÑÐµÑ ÑиÑоко извеÑÑное ÑоглаÑение о Ñом, ÑÑо ÑвойÑÑва, коÑоÑÑе наÑинаÑÑÑÑ Ñ Ñимвола "_", ÑвлÑÑÑÑÑ Ð²Ð½ÑÑÑенними, и к ним не ÑледÑÐµÑ Ð¾Ð±ÑаÑаÑÑÑÑ Ð¸Ð·-за пÑеделов обÑекÑа.
ÐÑполÑзование Ð´Ð»Ñ ÑовмеÑÑимоÑÑи
У акÑеÑÑоÑов еÑÑÑ Ð¸Ð½ÑеÑеÑÐ½Ð°Ñ Ð¾Ð±Ð»Ð°ÑÑÑ Ð¿ÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ â они позволÑÑÑ Ð² лÑбой Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð²Ð·ÑÑÑ Â«Ð¾Ð±ÑÑное» ÑвойÑÑво и измениÑÑ ÐµÐ³Ð¾ поведение, поменÑв на геÑÑÐµÑ Ð¸ ÑеÑÑеÑ.
ÐапÑимеÑ, пÑедÑÑавим, ÑÑо Ð¼Ñ Ð½Ð°Ñали ÑеализовÑваÑÑ Ð¾Ð±ÑÐµÐºÑ user, иÑполÑзÑÑ ÑвойÑÑва-даннÑе Ð¸Ð¼Ñ name и возÑаÑÑ age:
function User(name, age) {
this.name = name;
this.age = age;
}
let john = new User("John", 25);
alert( john.age ); // 25
â¦Ðо Ñано или поздно вÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑÑÑ. Ðзамен возÑаÑÑа age Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑеÑиÑÑ Ñ
ÑаниÑÑ Ð´Ð°ÑÑ ÑÐ¾Ð¶Ð´ÐµÐ½Ð¸Ñ birthday, поÑÐ¾Ð¼Ñ ÑÑо Ñак более ÑоÑно и Ñдобно:
function User(name, birthday) {
this.name = name;
this.birthday = birthday;
}
let john = new User("John", new Date(1992, 6, 1));
ЧÑо нам делаÑÑ Ñо ÑÑаÑÑм кодом, коÑоÑÑй иÑполÑзÑÐµÑ ÑвойÑÑво age?
ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ попÑÑаÑÑÑÑ Ð½Ð°Ð¹Ñи вÑе Ñакие меÑÑа и измениÑÑ Ð¸Ñ
, но ÑÑо оÑÐ½Ð¸Ð¼Ð°ÐµÑ Ð²ÑÐµÐ¼Ñ Ð¸ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½ÐµÐ²Ñполнимо, еÑли код иÑполÑзÑеÑÑÑ Ð´ÑÑгими лÑдÑми. РкÑоме Ñого, age â ÑÑо оÑлиÑное ÑвойÑÑво Ð´Ð»Ñ user, веÑно?
ÐавайÑе его ÑÐ¾Ñ Ñаним.
Ðобавление геÑÑеÑа Ð´Ð»Ñ age ÑеÑÐ¸Ñ Ð¿ÑоблемÑ:
function User(name, birthday) {
this.name = name;
this.birthday = birthday;
// возÑаÑÑ ÑаÑÑÑиÑÑваеÑÑÑ Ð¸Ð· ÑекÑÑей даÑÑ Ð¸ Ð´Ð½Ñ ÑождениÑ
Object.defineProperty(this, "age", {
get() {
let todayYear = new Date().getFullYear();
return todayYear - this.birthday.getFullYear();
}
});
}
let john = new User("John", new Date(1992, 6, 1));
alert( john.birthday ); // доÑÑÑпен как Ð´ÐµÐ½Ñ ÑождениÑ
alert( john.age ); // ...Ñак и возÑаÑÑ
ТепеÑÑ ÑÑаÑÑй код Ñоже ÑабоÑаеÑ, и Ñ Ð½Ð°Ñ ÐµÑÑÑ Ð¾ÑлиÑное дополниÑелÑное ÑвойÑÑво!

ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)