У пÑогÑамÑÐ²Ð°Ð½Ð½Ñ Ð¼Ð¸ ÑаÑÑо Ñ Ð¾Ñемо ÑоÑÑ Ð²Ð·ÑÑи Ñ Ð´Ð¾Ð¿Ð¾Ð²Ð½Ð¸Ñи Ñи ÑозÑиÑиÑи.
ÐапÑиклад, ми маÑмо обâÑÐºÑ user з його влаÑÑивоÑÑÑми Ñа меÑодами, Ñ Ñ
оÑемо ÑÑвоÑиÑи admin Ñа guest Ñк деÑо змÑÐ½ÐµÐ½Ñ Ð²Ð°ÑÑанÑи обâÑкÑа user. ТобÑо ми Ñ
оÑемо повÑоÑно викоÑиÑÑовÑваÑи Ñе, Ñо ми маÑмо в user, але Ñакож додаÑи Ñе влаÑÐ½Ñ Ð¼ÐµÑоди Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ. ÐнакÑе кажÑÑи, пÑоÑÑо Ñ
оÑемо збÑдÑваÑи новий обâÑÐºÑ Ð¿Ð¾Ð²ÐµÑÑ
Ñого, Ñо ÑÑнÑÑ.
УÑпадкÑÐ²Ð°Ð½Ð½Ñ ÑеÑез пÑоÑоÑипи â Ñе Ñе, Ñо нам допоможе в ÑÑомÑ.
СпеÑÑалÑна влаÑÑивÑÑÑÑ [[Prototype]]
Ð JavaScript, обâÑкÑи маÑÑÑ ÑпеÑÑалÑÐ½Ñ Ð¿ÑиÑ
Ð¾Ð²Ð°Ð½Ñ Ð²Ð»Ð°ÑÑивÑÑÑÑ [[Prototype]] (Ñк зазнаÑено в ÑпеÑиÑÑкаÑÑÑÑ
мови), Ñка може пÑиймаÑи знаÑеннÑ: або null, або маÑи поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° ÑнÑий обâÑкÑ. Цей обâÑÐºÑ Ð½Ð°Ð·Ð¸Ð²Ð°ÑÑÑÑÑ âпÑоÑоÑипâ:
Ðоли ми намагаÑмоÑÑ Ð·ÑиÑаÑи ÑкÑÑÑ Ð²Ð»Ð°ÑÑивÑÑÑÑ Ð¾Ð±âÑкÑа object, але ÑÑ Ð² нÑÐ¾Ð¼Ñ ÑÐ°Ð¼Ð¾Ð¼Ñ Ð½Ðµ маÑ, JavaScript авÑомаÑиÑно беÑе ÑÑ Ð· пÑоÑоÑипÑ. РпÑогÑамÑÐ²Ð°Ð½Ð½Ñ Ñе називаÑÑÑÑÑ âÑÑпадкÑÐ²Ð°Ð½Ð½Ñ ÑеÑез пÑоÑоÑипиâ. СкоÑо ми вивÑимо багаÑо пÑикладÑв Ñакого ÑÑпадкÑÐ²Ð°Ð½Ð½Ñ Ñа ÑÑвоÑимо ÑÑÐºÐ°Ð²Ñ Ð¿Ñиклади, ÑÐºÑ Ð¿Ð¾Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ñ Ð½Ð° ÑÑ
оÑновÑ.
Така влаÑÑивÑÑÑÑ [[Prototype]] Ñ Ð²Ð½ÑÑÑÑÑнÑÐ¾Ñ Ñа пÑиÑ
ованоÑ, але Ñ Ð±Ð°Ð³Ð°Ñо ÑлÑÑ
Ñв Ñоб ÑÑ Ð²ÑÑановиÑи.
Ðдним з ниÑ
Ñ Ð²Ð¸ÐºÐ¾ÑиÑÑÐ°Ð½Ð½Ñ ÑпеÑÑалÑного ÑÐ¼ÐµÐ½Ñ __proto__, напÑиклад:
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal; // ÑÑÑ Ð²ÑÑановлÑÑмо rabbit.[[Prototype]] = animal
Ð ÑепеÑ, ÑкÑо ми зÑиÑÑÑмо влаÑÑивÑÑÑÑ Ð· обâÑкÑа rabbit, а ÑÑ Ð½ÐµÐ¼Ð°Ñ, Ñо JavaScript авÑомаÑиÑно вÑзÑме ÑÑ Ð· animal.
ÐÑÑ Ñе пÑиклад:
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal; // (*)
// ÑÐµÐ¿ÐµÑ Ð¼Ð¸ можемо знайÑи Ð¾Ð±Ð¸Ð´Ð²Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð² обâÑкÑÑ rabbit:
alert( rabbit.eats ); // true (**)
alert( rabbit.jumps ); // true
РпознаÑÐµÐ½Ð¾Ð¼Ñ (*) ÑÑдкÑ, обâÑÐºÑ animal вÑÑановлÑÑÑÑÑÑ Ñк пÑоÑоÑип Ð´Ð»Ñ Ð¾Ð±âÑкÑа rabbit.
Рколи alert намагаÑÑÑÑÑ Ð¿ÑоÑиÑаÑи влаÑÑивÑÑÑÑ rabbit.eats (ÑÑдок познаÑено (**)), а ÑÑ Ñам немаÑ, Ñо JavaScript йде за поÑиланнÑм [[Prototype]] Ñа знаÑ
одиÑÑ ÑÑ Ð² обâÑкÑÑ animal (дивÑÑÑÑÑ Ð·Ð½Ð¸Ð·Ñ Ð²Ð²ÐµÑÑ
):
Ðи можемо ÑказаÑи, Ñо âanimal Ñ Ð¿ÑоÑоÑипом Ð´Ð»Ñ rabbitâ, або Ñо âобâÑÐºÑ rabbit ÑÑпадковÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð¾Ð±âÑкÑа animalâ.
ЯкÑо animal Ð¼Ð°Ñ Ð±Ð°Ð³Ð°Ñо коÑиÑниÑ
влаÑÑивоÑÑей Ñа меÑодÑв, вони ÑÑаÑÑÑ Ð°Ð²ÑомаÑиÑно доÑÑÑпними Ð´Ð»Ñ rabbit. Ð¢Ð°ÐºÑ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð½Ð°Ð·Ð¸Ð²Ð°ÑÑÑÑÑ âÑÑпадкованимиâ.
Також, ÑкÑо ми маÑмо меÑоди в animal, Ñо вони можÑÑÑ Ð±ÑÑи Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ð½Ñ Ñ Ð² rabbit:
let animal = {
eats: true,
walk() {
alert("ТваÑина йде");
}
};
let rabbit = {
jumps: true,
__proto__: animal
};
// ÑÑÑ Ð¼ÐµÑод walk беÑеÑÑÑÑ Ð· пÑоÑоÑипÑ
rabbit.walk(); // оÑÑимÑÑмо "ТваÑина йде"
ÐеÑоди авÑомаÑиÑно беÑÑÑÑÑÑ Ð· пÑоÑоÑипÑ, Ñк ÑÑÑ:
ÐанÑÑг пÑоÑоÑипÑв може бÑÑи навÑÑÑ Ð´Ð¾Ð²Ñим:
let animal = {
eats: true,
walk() {
alert("ТваÑина йде");
}
};
let rabbit = {
jumps: true,
__proto__: animal
};
let longEar = {
earLength: 10,
__proto__: rabbit
};
// ÐеÑод walk беÑемо з ланÑÑжка пÑоÑоÑипÑв
longEar.walk(); // оÑÑимÑÑмо "ТваÑина йде"
alert(longEar.jumps); // true (беÑеÑÑÑÑ Ð· обâÑкÑа rabbit)
Ð ÑепеÑ, ÑкÑо ми Ñ
оÑемо взÑÑи меÑод з обâÑкÑа longEar, а його Ñам немаÑ, JavaScript бÑде ÑÑкаÑи його в rabbit, а Ð´Ð°Ð»Ñ Ð² animal.
ÐÑнÑÑ Ð´Ð²Ð° обмеженнÑ:
- ÐоÑÐ¸Ð»Ð°Ð½Ð½Ñ ÑеÑез пÑоÑоÑипи не може бÑÑи замкнено в кÑлÑÑе. JavaScript видаÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ, ÑкÑо ми визнаÑимо
__proto__в ланÑÑÐ¶ÐºÑ Ð¿ÑоÑоÑипÑв Ñ Ð·Ð°Ð¼ÐºÐ½ÐµÐ¼ його в кÑлÑÑе. - ÐнаÑеннÑ
__proto__може бÑÑи або поÑиланнÑм на обâÑкÑ, абоnull. ÐнÑÑ Ñипи знаÑÐµÐ½Ñ ÑгноÑÑÑÑÑÑÑ.
Ð¥Ð¾Ñ Ñе Ñ Ð¾Ñевидно, але вÑе ж Ñаки: може бÑÑи ÑÑлÑки одна влаÑÑивÑÑÑÑ [[Prototype]]. ÐбâÑÐºÑ Ð½Ðµ може ÑÑпадковÑваÑи влаÑÑивоÑÑÑ Ñа меÑоди вÑд двоÑ
пÑоÑоÑипÑв одноÑаÑно.
__proto__ Ñ ÑÑаÑим Ñ Ð´Ð°Ð²Ð½Ñм getter/setter Ð´Ð»Ñ [[Prototype]]ÐважаÑÑÑÑÑ Ð¿Ð¾ÑиÑÐµÐ½Ð¾Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¾Ñ, оÑобливо Ð´Ð»Ñ Ð¿Ð¾ÑаÑкÑвÑÑв, неможливÑÑÑÑ ÑÑÑко визнаÑиÑи ÑÑзниÑÑ Ð¼Ñж двома понÑÑÑÑми __proto__ Ñа [[Prototype]].
ÐÑÐ´Ñ Ð»Ð°Ñка заÑважÑе, Ñо влаÑÑивÑÑÑÑ __proto__ не Ñ ÑÐ¾Ñ ÑÐ°Ð¼Ð¾Ñ Ð²Ð»Ð°ÑÑивÑÑÑÑ Ñк внÑÑÑÑÑÐ½Ñ Ð²Ð»Ð°ÑÑивÑÑÑÑ [[Prototype]]. Це Ñ getter/setter Ð´Ð»Ñ [[Prototype]]. ÐÑзнÑÑе ми побаÑимо ÑиÑÑаÑÑÑ, коли Ñе важливо, а поки Ñо давайÑе пÑоÑÑо маÑи Ñе на ÑвазÑ, пÑимножÑÑÑи ÑÐ²Ð¾Ñ ÑозÑмÑÐ½Ð½Ñ Ð¼Ð¾Ð²Ð¸ JavaScript.
ÐлаÑÑивÑÑÑÑ __proto__ вважаÑÑÑÑÑ ÑÑоÑ
и заÑÑаÑÑлоÑ. Ðона ÑÑнÑÑ Ð· ÑÑÑоÑиÑниÑ
пÑиÑин, ÑÑÑаÑна мова JavaScript пÑопонÑÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑваÑи ÑÑнкÑÑÑ Object.getPrototypeOf/Object.setPrototypeOf замÑÑÑÑ get/set пÑоÑоÑипÑ. Ðи Ñакож ÑозглÑнемо ÑÑ ÑÑнкÑÑÑ Ð¿ÑзнÑÑе.
ÐгÑдно Ð·Ñ ÑпеÑиÑÑкаÑÑÑÑ Ð¼Ð¾Ð²Ð¸, __proto__ Ð¼Ð°Ñ Ð¿ÑдÑÑимÑваÑиÑÑ ÑÑлÑки в бÑаÑзеÑаÑ
. ÐÑоÑе наÑпÑавдÑ, ÑÑÑ ÑеÑедовиÑа, вклÑÑаÑÑи ÑеÑвеÑнÑ, пÑдÑÑимÑÑÑÑ __proto__, а ÑÐ¾Ð¼Ñ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑваÑи його можна доÑиÑÑ Ð±ÐµÐ·Ð¿ÐµÑно.
ÐÑкÑлÑки познаÑÐµÐ½Ð½Ñ __proto__ ÑнÑÑÑÑивно бÑлÑÑ Ð·ÑозÑмÑле, ми бÑдемо його викоÑиÑÑовÑÑмо в пÑикладаÑ
.
ÐпеÑаÑÑÑ Ð¿Ð¾ запиÑÑ/Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð½Ðµ заÑÑоÑовÑÑÑÑÑÑ Ð½Ð° пÑоÑоÑипаÑ
ÐÑоÑоÑипи можна викоÑиÑÑовÑваÑи ÑÑлÑки Ð´Ð»Ñ Ð·ÑиÑÑÐ²Ð°Ð½Ð½Ñ Ð²Ð»Ð°ÑÑивоÑÑей.
Ð ÑÐ°ÐºÑ Ð¾Ð¿ÐµÑаÑÑÑ Ñк запиÑ/видаленнÑ, пÑаÑÑÑÑÑ Ð½Ð°Ð¿ÑÑÐ¼Ñ ÑÑлÑки на ÑÐ°Ð¼Ð¾Ð¼Ñ Ð¾Ð±âÑкÑÑ.
У пÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð½Ð¸Ð¶Ñе, ми визнаÑаÑмо влаÑний меÑод walk Ð´Ð»Ñ Ð¾Ð±âÑкÑа rabbit:
let animal = {
eats: true,
walk() {
/* Ñей меÑод не бÑде викоÑиÑÑаний обâÑкÑом rabbit */
}
};
let rabbit = {
__proto__: animal
};
rabbit.walk = function() {
alert("ÐÑолик! СкÑк-ÑкÑк!");
};
rabbit.walk(); // ÑÑÑ Ð¾ÑÑимаÑмо 'ÐÑолик! СкÑк-ÑкÑк!'
Як ÑÑлÑки ми задали меÑод rabbit.walk() Ñаким Ñином, пÑи Ð²Ð¸ÐºÐ»Ð¸ÐºÑ ÑÑÑÑй одÑÐ°Ð·Ñ Ð·Ð½Ð°Ð¹Ð´Ðµ його на ÑÐ°Ð¼Ð¾Ð¼Ñ Ð¾Ð±âÑкÑÑ Ñа Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ Ð±ÐµÐ· викоÑиÑÑÐ°Ð½Ð½Ñ Ñакого Ñамого меÑодÑ, Ñкий визнаÑений в пÑоÑоÑипÑ:
ÐлаÑÑивоÑÑÑ âAccessorâ Ñ Ð²Ð¸Ð½ÑÑком, оÑкÑлÑки пÑиÑвоÑÐ½Ð½Ñ Ð¾Ð±ÑоблÑÑÑÑÑÑ ÑÑнкÑÑÑÑ Ð²ÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ (ÑеÑез âsetterâ). ТобÑо, коли ми намагаÑмоÑÑ Ð·Ð°Ð¿Ð¸ÑаÑи знаÑÐµÐ½Ð½Ñ Ñ ÑÐ°ÐºÑ Ð²Ð»Ð°ÑÑивÑÑÑÑ, вÑдбÑваÑÑÑÑÑ Ð·ÑиÑÑÐ²Ð°Ð½Ð½Ñ Ñ Ð·Ð°Ð¿ÑÑк ÑÑнкÑÑÑ, поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° ÑÐºÑ Ð·Ð±ÐµÑÑгаÑÑÑÑÑ Ð² ÑÑй влаÑÑивоÑÑÑ.
Ð ÑÑÑÑ Ð¿ÑиÑини admin.fullName коÑекÑно пÑаÑÑÑ Ð² кодÑ, Ñо показаний нижÑе:
let user = {
name: "John",
surname: "Smith",
set fullName(value) {
[this.name, this.surname] = value.split(" ");
},
get fullName() {
return `${this.name} ${this.surname}`;
}
};
let admin = {
__proto__: user,
isAdmin: true
};
alert(admin.fullName); // John Smith (*)
// вÑдпÑаÑÑовÑÑ setter
admin.fullName = "Alice Cooper"; // (**)
alert(admin.fullName); // Alice Cooper, ÑÑан обâÑкÑа admin бÑло змÑнено
alert(user.fullName); // John Smith, ÑÑан обâÑкÑа user заÑ
иÑено
ТÑÑ Ð½Ð° ÑÑÐ´ÐºÑ Ð¿Ð¾Ð·Ð½Ð°ÑÐµÐ½Ð¾Ð¼Ñ (*), влаÑÑивÑÑÑÑ admin.fullName викликаÑÑÑÑÑ ÑеÑез getter, визнаÑений в пÑоÑоÑÐ¸Ð¿Ñ user. Рна ÑÑÐ´ÐºÑ Ð¿Ð¾Ð·Ð½Ð°ÑÐµÐ½Ð¾Ð¼Ñ (**) влаÑÑивÑÑÑÑ Ð·Ð°Ð´Ð°ÑÑÑÑÑ ÑеÑез setter, Ñкий Ñакож визнаÑений в пÑоÑоÑипÑ.
ÐнаÑÐµÐ½Ð½Ñ ÐºÐ»ÑÑового Ñлова âthisâ
ЦÑкаве пиÑÐ°Ð½Ð½Ñ Ð¼Ð¾Ð¶Ðµ виникнÑÑи в пÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð²Ð¸Ñе: Ñке знаÑÐµÐ½Ð½Ñ ÐºÐ»ÑÑового Ñлова this вÑеÑÐµÐ´Ð¸Ð½Ñ set fullName(value)? Ðе визнаÑаÑÑÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ this.name Ñа this.surname: в обâÑкÑÑ user Ñи admin?
ÐÑдповÑÐ´Ñ Ð¿ÑоÑÑа: на this не Ð²Ð¿Ð»Ð¸Ð²Ð°Ñ Ð¿ÑоÑоÑип ÑзагалÑ.
Ðезалежно вÑд Ñого, де меÑод визнаÑений: в обâÑкÑÑ Ñи його пÑоÑоÑипÑ, клÑÑове Ñлово this завжди вказÑÑ Ð½Ð° обâÑÐºÑ Ð¿ÐµÑед кÑапкоÑ.
Таким Ñином, виклик в меÑÐ¾Ð´Ñ set виÑÐ°Ð·Ñ admin.fullName= бÑде бÑаÑи Ñк this знаÑÐµÐ½Ð½Ñ Ð²Ð»Ð°ÑÑивоÑÑей з обâÑкÑÑ admin а не user.
Це дÑже важлива ÑÑÑ, бо напÑиклад, ми можемо маÑи дÑже великий обâÑÐºÑ Ð· багаÑÑма меÑодами, Ñ Ð¾Ð±âÑкÑи, ÑÐºÑ ÑÑпадковÑÑÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð°Ð±Ð¾ меÑоди вÑд Ñого великого баÑÑкÑвÑÑкого обâÑкÑÑ. Ð, ÑкÑо ми вÑзÑмемо ÑÑпадкований обâÑкÑ, поÑÑавимо пÑÑÐ»Ñ Ð¹Ð¾Ð³Ð¾ ÑÐ¼ÐµÐ½Ñ ÐºÑÐ°Ð¿ÐºÑ Ñ Ð´Ð°Ð»Ñ Ð²Ð¸ÐºÐ»Ð¸Ñемо меÑод, Ñкий збеÑÑгаÑÑÑÑÑ Ð² ÑÐ¾Ð¼Ñ âбаÑÑкÑвÑÑкомÑâ Ð²ÐµÐ»Ð¸ÐºÐ¾Ð¼Ñ Ð¾Ð±âÑкÑÑ, Ñо Ñей меÑод змÑниÑÑ ÑÑан лиÑе Ñамого ÑÑпадкованого обâÑкÑа. Ðа ÑÑан Ñого великого âбаÑÑкÑвÑÑкогоâ обâÑкÑа в ÑÑй ÑиÑÑаÑÑÑ Ñей меÑод не вплине.
У ÑÑÐ¾Ð¼Ñ Ð¿ÑикладÑ, обâÑÐºÑ animal Ð½Ð°Ð´Ð°Ñ âнабÑÑ Ð¼ÐµÑодÑвâ, а обâÑÐºÑ rabbit може викоÑиÑÑовÑваÑи ÑкÑÑÑ Ð· ÑиÑ
меÑодÑв.
Ðиклик rabbit.sleep() вÑÑановлÑÑ this.isSleeping в обâÑкÑÑ rabbit:
// обâÑÐºÑ animal Ð¼Ð°Ñ Ð½Ð°Ð±ÑÑ Ð¼ÐµÑодÑв has
let animal = {
walk() {
if (!this.isSleeping) {
alert(`Я Ñ
оджÑ`);
}
},
sleep() {
this.isSleeping = true;
}
};
let rabbit = {
name: "ÐÑлий кÑолик",
__proto__: animal
};
// змÑнÑÑ ÑÑлÑки ÑвÑй ÑÑан меÑодом rabbit.isSleeping
rabbit.sleep();
alert(rabbit.isSleeping); // true
alert(animal.isSleeping); // undefined (Ð½ÐµÐ¼Ð°Ñ ÑÐ°ÐºÐ¾Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð² пÑоÑоÑипÑ)
ÐÑÑаÑоÑний виглÑд:
ЯкÑо ми маÑмо ÑнÑÑ Ð¾Ð±âÑкÑи: bird, snake ÑоÑо, ÑÐºÑ ÑÑÐ¿Ð°Ð´ÐºÐ¾Ð²Ð°Ð½Ñ Ð²Ñд обâÑкÑа animal, вони Ñакож бÑдÑÑÑ Ð¼Ð°Ñи доÑÑÑп до меÑодÑв animal. Ðожний Ñаз, пÑи Ð²Ð¸ÐºÐ»Ð¸ÐºÑ Ð±ÑдÑ-Ñкого меÑодÑ, клÑÑове Ñлово this бÑде вказÑваÑи на Ñой обâÑкÑ, вÑдноÑно Ñкого бÑв викликаний Ñей меÑод, а не на обâÑÐºÑ animal. ÐÑже, коли ми запиÑÑÑмо бÑдÑ-ÑÐºÑ Ð´Ð°Ð½Ñ Ð² this, вони збеÑÑгаÑÑÑÑÑ Ð² обâÑкÑаÑ
на ÑÐºÑ Ñ Ð²ÐºÐ°Ð·ÑÑ this.
Як ÑезÑлÑÑаÑ, меÑоди можÑÑÑ ÑÑпадковÑваÑиÑÑ (пеÑедаваÑиÑÑ), але ÑÑани обâÑкÑÑв â не можÑÑÑ.
Цикл forâ¦in
Цикл for..in пÑоÑ
одиÑÑ Ñакож по ÑÑпадкованиÑ
влаÑÑивоÑÑÑÑ
.
ÐапÑиклад:
let animal = {
eats: true
};
let rabbit = {
jumps: true,
__proto__: animal
};
// Object.keys повеÑÑÐ°Ñ ÑÑлÑки влаÑÐ½Ñ ÐºÐ»ÑÑÑ
alert(Object.keys(rabbit)); // jumps
// Цикл for..in повеÑÑÐ°Ñ Ñк влаÑнÑ, Ñак Ñ ÑÑÐ¿Ð°Ð´ÐºÐ¾Ð²Ð°Ð½Ñ ÐºÐ»ÑÑÑ
for(let prop in rabbit) alert(prop); // jumps, поÑÑм eats
ЯкÑо Ñе не Ñе, Ñо нам поÑÑÑбно, Ñ Ð¼Ð¸ б Ñ
оÑÑли виклÑÑиÑи оÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ ÑÑпадкованиÑ
знаÑенÑ, ÑÑнÑÑ Ð²Ð±Ñдований меÑод obj.hasOwnProperty(key), Ñкий повеÑÑÐ°Ñ true ÑкÑо влаÑÑивÑÑÑÑ key обâÑкÑа obj Ñ Ð¹Ð¾Ð³Ð¾ влаÑноÑ, а не ÑÑпадкованоÑ.
ÐÑже, ми можемо вÑдÑÑлÑÑÑÑваÑи ÑÑÐ¿Ð°Ð´ÐºÐ¾Ð²Ð°Ð½Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ (Ñи зÑобиÑи з ними ÑоÑÑ ÑнÑе):
let animal = {
eats: true
};
let rabbit = {
jumps: true,
__proto__: animal
};
for(let prop in rabbit) {
let isOwn = rabbit.hasOwnProperty(prop);
if (isOwn) {
alert(`ÐаÑ: ${prop}`); // ÐаÑ: jumps
} else {
alert(`УÑпадковано: ${prop}`); // УÑпадковано: eats
}
}
У ÑÑÐ¾Ð¼Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð¼Ð¸ маÑмо наÑÑÑпний ланÑÑжок: rabbit ÑÑпадковÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð²Ñд обâÑкÑа animal, Ñкий, Ñ ÑÐ²Ð¾Ñ ÑеÑгÑ, ÑÑпадковÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð²Ñд глобалÑного Object.prototype (бо animal Ñипово Ñ Ð»ÑÑеÑалом обâÑкÑа {...}) Ñ Ð½Ð° ÑÐ°Ð¼Ð¾Ð¼Ñ Ð²ÐµÑÑ
Ñ Ð¼Ð°Ñмо null:
ÐаÑважÑе Ð¾Ð´Ð½Ñ ÑÑÐºÐ°Ð²Ñ ÑÑÑ: звÑдки Ð²Ð·Ð°Ð³Ð°Ð»Ñ Ð²Ð·ÑвÑÑ Ð¼ÐµÑод rabbit.hasOwnProperty? Ðи його не визнаÑали. ÐивлÑÑиÑÑ Ð½Ð° ланÑÑжок ÑÑпадкÑÐ²Ð°Ð½Ñ Ð¼Ð¸ можемо побаÑиÑи, Ñо його визнаÑÐµÐ½Ð½Ñ Ð¹Ð´Ðµ вÑд Object.prototype.hasOwnProperty. ÐнакÑе кажÑÑи, вÑн ÑÑпадковÑÑÑÑÑÑ.
â¦Ð°Ð»Ðµ ÑÐ¾Ð¼Ñ Ð¼ÐµÑод hasOwnProperty не зâÑвлÑÑÑÑÑÑ Ð² ÑÐ¸ÐºÐ»Ñ for..in поÑÑд з ÑнÑими влаÑÑивоÑÑÑми (eats Ñа jumps), ÑкÑо Ñам Ñикл for..in ÑÑеÑÑÑ Ð°Ð±Ð¾ пÑоÑ
одиÑÑ Ð² ÑÐ¾Ð¼Ñ ÑиÑÐ»Ñ ÑÑпадкованими влаÑÑивоÑÑÑм?
ÐÑдповÑÐ´Ñ Ð¿ÑоÑÑа: вони познаÑÐµÐ½Ñ (Ñе можна ÑказаÑи, Ñо в ниÑ
ÑÑоÑÑÑ Ð¿ÑапоÑÑÑ) Ñк ÑакÑ, Ñо ÑÑ
не можна пеÑеÑаÑ
овÑваÑи (not enumerable). Так Ñамо Ñк Ñ ÑнÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð² глобалÑÐ½Ð¾Ð¼Ñ Ð¾Ð±âÑкÑÑ Object.prototype. У ÑиÑ
влаÑÑивоÑÑей пÑапоÑеÑÑ ÑÑоÑÑÑ Ñк enumerable:false, а Ñикл for..in зÑиÑÑÑ ÑÑлÑки ÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ, ÑÐºÑ Ð¿Ð¾Ð·Ð½Ð°ÑÐµÐ½Ñ Ñк ÑакÑ, Ñо ÑÑ
можна пеÑеÑаÑ
овÑваÑи. ÐÑÑ ÑÐ¾Ð¼Ñ Ñ ÑеÑÑа влаÑÑивоÑÑей глобалÑного обâÑкÑÑ Object.prototype не зÑиÑÑÑÑÑÑÑ Ñакож.
Ðайже вÑÑ ÑнÑÑ Ð¼ÐµÑоди Ð´Ð»Ñ Ð¾ÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ Ð¿Ð°Ñ ÐºÐ»ÑÑ/знаÑеннÑ, ÑÐ°ÐºÑ Ñк Ð¾Ñ Object.keys, Object.values Ñа ÑнÑÑ, ÑгноÑÑÑÑÑ ÑÑÐ¿Ð°Ð´ÐºÐ¾Ð²Ð°Ð½Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ.
Ðони пÑаÑÑÑÑÑ Ð»Ð¸Ñе з влаÑÑивоÑÑÑми Ñамого обâÑкÑа Ñ Ð½Ðµ ÑÑпаÑÑÑ Ð²Ð»Ð°ÑÑивоÑÑей з його пÑоÑоÑипÑв.
ÐÑдÑÑмки
- Ð JavaScript, ÑÑÑ Ð¾Ð±âÑкÑи маÑÑÑ Ð¿ÑиÑ
Ð¾Ð²Ð°Ð½Ñ Ð²Ð»Ð°ÑÑивÑÑÑÑ
[[Prototype]], Ñка може поÑилаÑиÑÑ Ð½Ð° ÑнÑий обâÑÐºÑ Ð°Ð±Ð¾ бÑÑиnull. - Ðи можемо викоÑиÑÑаÑи
obj.__proto__Ð´Ð»Ñ Ð´Ð¾ÑÑÑÐ¿Ñ Ð´Ð¾ ÑÑÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ (Ñе ÑÑÑоÑиÑний getter/setter; Ñ Ð¹ ÑнÑÑ Ð¼ÐµÑоди, ÑÐºÑ ÑозглÑнемо згодом). - ÐбâÑкÑ, на Ñкий поÑилаÑÑÑÑÑ Ð²Ð»Ð°ÑÑивÑÑÑÑ
[[Prototype]]називаÑÑÑÑÑ âпÑоÑоÑипâ. - ЯкÑо ми Ñ
оÑемо пÑоÑиÑаÑи влаÑÑивоÑÑÑ Ð¾Ð±âÑкÑа
objÑи викликаÑи меÑод, ÑÐºÐ¸Ñ Ð½Ðµ ÑÑнÑÑ, ÑÐ¾Ð´Ñ JavaScript намагаÑÑÑÑÑ Ð·Ð½Ð°Ð¹Ñи ÑÑ Ð² пÑоÑоÑипÑ. - ÐпеÑаÑÑÑ Ð¿Ð¾ запиÑÑ/Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð¿ÑаÑÑÑÑÑ Ð±ÐµÐ·Ð¿Ð¾ÑеÑеднÑо з обâÑкÑом. Ðони не заÑÑпаÑÑÑ Ð¿ÑоÑоÑип (ÑкÑо ми запÑÑкаÑмо ÑÐ°ÐºÑ Ð¾Ð¿ÐµÑаÑÑÑ Ð· звиÑÐ°Ð¹Ð½Ð¾Ñ Ð²Ð»Ð°ÑÑивÑÑÑÑ, а не з ÑеÑÑеÑом).
- ЯкÑо ми викликаÑмо
obj.method(), Ñ Ð¿Ñи ÑÑомÑ,methodбеÑеÑÑÑÑ Ð· пÑоÑоÑипÑ, клÑÑове ÑловоthisвÑеодно бÑде вказÑваÑи наobj. Таким Ñином, меÑоди завжди пÑаÑÑÑÑÑ Ð· поÑоÑним обâÑкÑом, навÑÑÑ, ÑкÑо ÑÑ Ð¼ÐµÑоди ÑÑпадкованÑ. - Цикл
for..inÑÑеÑÑÑ Ñк по влаÑнÑ, Ñак Ñ ÑÑÐ¿Ð°Ð´ÐºÐ¾Ð²Ð°Ð½Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ. УÑÑ ÑнÑÑ Ð¼ÐµÑоди з оÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ Ð¿Ð°Ñ ÐºÐ»ÑÑ/знаÑÐµÐ½Ð½Ñ Ð¿ÑаÑÑÑÑÑ ÑÑлÑки з влаÑними влаÑÑивоÑÑÑми обâÑкÑа.
ÐоменÑаÑÑ
<code>, Ð´Ð»Ñ ÐºÑлÑÐºÐ¾Ñ ÑÑдкÑв â обгоÑнÑÑÑ ÑÑ Ñегом<pre>, Ð´Ð»Ñ Ð¿Ð¾Ð½Ð°Ð´ 10 ÑÑдкÑв â викоÑиÑÑовÑйÑе пÑÑоÑниÑÑ (plnkr, jsbin, codepenâ¦)