Ðак Ð¼Ñ Ð¿Ð¾Ð¼Ð½Ð¸Ð¼, новÑе обÑекÑÑ Ð¼Ð¾Ð³ÑÑ Ð±ÑÑÑ ÑÐ¾Ð·Ð´Ð°Ð½Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÑнкÑии-конÑÑÑÑкÑоÑа new F().
ÐÑли в F.prototype ÑодеÑжиÑÑÑ Ð¾Ð±ÑекÑ, опеÑаÑÐ¾Ñ new ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÐµÐ³Ð¾ в каÑеÑÑве [[Prototype]] Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ обÑекÑа.
JavaScript иÑполÑзовал пÑоÑоÑипное наÑледование Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñа Ñвоего поÑвлениÑ. ÐÑо одна из оÑновнÑÑ Ð¾ÑобенноÑÑей ÑзÑка.
Ðо ÑанÑÑе, в ÑÑаÑÑе вÑемена, пÑÑмого доÑÑÑпа к пÑоÑоÑÐ¸Ð¿Ñ Ð¾Ð±ÑекÑа не бÑло. ÐадÑжно ÑабоÑало ÑолÑко ÑвойÑÑво "prototype" ÑÑнкÑии-конÑÑÑÑкÑоÑа, опиÑанное в ÑÑой главе. ÐоÑÑÐ¾Ð¼Ñ Ð¾Ð½Ð¾ иÑполÑзÑеÑÑÑ Ð²Ð¾ многиÑ
ÑкÑипÑаÑ
.
ÐбÑаÑиÑе внимание, ÑÑо F.prototype ознаÑÐ°ÐµÑ Ð¾Ð±ÑÑное ÑвойÑÑво Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ "prototype" Ð´Ð»Ñ F. ÐÑо еÑÑ Ð½Ðµ «пÑоÑоÑип обÑекÑа», а обÑÑное ÑвойÑÑво F Ñ Ñаким именем.
ÐÑиведÑм пÑимеÑ:
let animal = {
eats: true
};
function Rabbit(name) {
this.name = name;
}
Rabbit.prototype = animal;
let rabbit = new Rabbit("White Rabbit"); // rabbit.__proto__ == animal
alert( rabbit.eats ); // true
УÑÑановка Rabbit.prototype = animal бÑквалÑно говоÑÐ¸Ñ Ð¸Ð½ÑеÑпÑеÑаÑоÑÑ ÑледÑÑÑее: «ÐÑи Ñоздании обÑекÑа ÑеÑез new Rabbit() запиÑи ÐµÐ¼Ñ animal в [[Prototype]]».
РезÑлÑÑÐ°Ñ Ð±ÑÐ´ÐµÑ Ð²ÑглÑдеÑÑ Ñак:
Ðа изобÑажении: "prototype" â гоÑизонÑалÑÐ½Ð°Ñ ÑÑÑелка, обознаÑаÑÑÐ°Ñ Ð¾Ð±ÑÑное ÑвойÑÑво Ð´Ð»Ñ "F", а [[Prototype]] â веÑÑикалÑнаÑ, обознаÑаÑÑÐ°Ñ Ð½Ð°Ñледование rabbit Ð¾Ñ animal.
F.prototype иÑполÑзÑеÑÑÑ ÑолÑко в Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð²Ñзова new FF.prototype иÑполÑзÑеÑÑÑ ÑолÑко пÑи вÑзове new F и пÑиÑваиваеÑÑÑ Ð² каÑеÑÑве ÑвойÑÑва [[Prototype]] нового обÑекÑа.
ÐÑли поÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑвойÑÑво F.prototype измениÑÑÑ (F.prototype = <дÑÑгой обÑекÑ>), Ñо новÑе обÑекÑÑ, ÑозданнÑе Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ new F, бÑдÑÑ Ð¸Ð¼ÐµÑÑ Ð² каÑеÑÑве [[Prototype]] дÑÑгой обÑекÑ, а Ñже ÑÑÑеÑÑвÑÑÑие обÑекÑÑ ÑоÑ
ÑанÑÑ ÑÑаÑÑй.
F.prototype по ÑмолÑаниÑ, ÑвойÑÑво constructor
У каждой ÑÑнкÑии (за иÑклÑÑением ÑÑÑелоÑнÑÑ
) по ÑмолÑÐ°Ð½Ð¸Ñ Ñже еÑÑÑ ÑвойÑÑво "prototype".
Ðо ÑмолÑÐ°Ð½Ð¸Ñ "prototype" â обÑÐµÐºÑ Ñ ÐµÐ´Ð¸Ð½ÑÑвеннÑм ÑвойÑÑвом constructor, коÑоÑое ÑÑÑлаеÑÑÑ Ð½Ð° ÑÑнкÑиÑ-конÑÑÑÑкÑоÑ.
ÐÐ¾Ñ Ñакой:
function Rabbit() {}
/* пÑоÑоÑип по ÑмолÑаниÑ
Rabbit.prototype = { constructor: Rabbit };
*/
ÐÑовеÑим ÑÑо:
function Rabbit() {}
// по ÑмолÑаниÑ:
// Rabbit.prototype = { constructor: Rabbit }
alert( Rabbit.prototype.constructor == Rabbit ); // true
СооÑвеÑÑÑвенно, еÑли Ð¼Ñ Ð½Ð¸Ñего не менÑем, Ñо ÑвойÑÑво constructor бÑÐ´ÐµÑ Ð´Ð¾ÑÑÑпно вÑем кÑоликам ÑеÑез [[Prototype]]:
function Rabbit() {}
// по ÑмолÑаниÑ:
// Rabbit.prototype = { constructor: Rabbit }
let rabbit = new Rabbit(); // наÑледÑÐµÑ Ð¾Ñ {constructor: Rabbit}
alert(rabbit.constructor == Rabbit); // true (ÑвойÑÑво полÑÑено из пÑоÑоÑипа)
ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ ÑвойÑÑво constructor ÑÑÑеÑÑвÑÑÑего обÑекÑа Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾.
ÐÑимеÑ:
function Rabbit(name) {
this.name = name;
alert(name);
}
let rabbit = new Rabbit("White Rabbit");
let rabbit2 = new rabbit.constructor("Black Rabbit");
ÐÑо Ñдобно, когда Ñ Ð½Ð°Ñ ÐµÑÑÑ Ð¾Ð±ÑекÑ, но Ð¼Ñ Ð½Ðµ знаем, какой конÑÑÑÑкÑÐ¾Ñ Ð¸ÑполÑзовалÑÑ Ð´Ð»Ñ ÐµÐ³Ð¾ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ (напÑимеÑ, он мог бÑÑÑ Ð²Ð·ÑÑ Ð¸Ð· ÑÑоÑонней библиоÑеки), а нам Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ ÑоздаÑÑ ÐµÑÑ Ð¾Ð´Ð¸Ð½ Ñакой обÑекÑ.
Ðо, пожалÑй, Ñамое важное о ÑвойÑÑве "constructor" ÑÑо Ñо, ÑÑоâ¦
â¦JavaScript Ñам по Ñебе не гаÑанÑиÑÑÐµÑ Ð¿ÑавилÑное знаÑение ÑвойÑÑва "constructor".
Ðа, оно ÑвлÑеÑÑÑ ÑвойÑÑвом по ÑмолÑÐ°Ð½Ð¸Ñ Ð² "prototype" Ñ ÑÑнкÑий, но ÑÑо ÑлÑÑиÑÑÑ Ñ Ð½Ð¸Ð¼ позже â завиÑÐ¸Ñ ÑолÑко Ð¾Ñ Ð½Ð°Ñ.
Ð ÑаÑÑноÑÑи, еÑли Ð¼Ñ Ð·Ð°Ð¼ÐµÐ½Ð¸Ð¼ пÑоÑоÑип по ÑмолÑÐ°Ð½Ð¸Ñ Ð½Ð° дÑÑгой обÑекÑ, Ñо ÑвойÑÑва "constructor" в нÑм не бÑдеÑ.
ÐапÑимеÑ:
function Rabbit() {}
Rabbit.prototype = {
jumps: true
};
let rabbit = new Rabbit();
alert(rabbit.constructor === Rabbit); // false
Таким обÑазом, ÑÑÐ¾Ð±Ñ ÑоÑ
ÑаниÑÑ Ð²ÐµÑное ÑвойÑÑво "constructor", Ð¼Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑ/ÑдалÑÑÑ/изменÑÑÑ ÑвойÑÑва Ñ Ð¿ÑоÑоÑипа по ÑмолÑÐ°Ð½Ð¸Ñ Ð²Ð¼ÐµÑÑо Ñого, ÑÑÐ¾Ð±Ñ Ð¿ÐµÑезапиÑÑваÑÑ ÐµÐ³Ð¾ Ñеликом:
function Rabbit() {}
// Ðе пеÑезапиÑÑваем Rabbit.prototype полноÑÑÑÑ,
// а добавлÑем к Ð½ÐµÐ¼Ñ ÑвойÑÑво
Rabbit.prototype.jumps = true
// ÐÑоÑоÑип по ÑмолÑÐ°Ð½Ð¸Ñ ÑоÑ
ÑанÑеÑÑÑ, и Ð¼Ñ Ð²ÑÑ ÐµÑÑ Ð¸Ð¼ÐµÐµÐ¼ доÑÑÑп к Rabbit.prototype.constructor
Ðли Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ заново ÑоздаÑÑ ÑвойÑÑво constructor:
Rabbit.prototype = {
jumps: true,
constructor: Rabbit
};
// ÑепеÑÑ ÑвойÑÑво constructor Ñнова коÑÑекÑное, Ñак как Ð¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ð»Ð¸ его
ÐÑого
Ð ÑÑой главе Ð¼Ñ ÐºÑаÑко опиÑали ÑпоÑоб Ð·Ð°Ð´Ð°Ð½Ð¸Ñ [[Prototype]] Ð´Ð»Ñ Ð¾Ð±ÑекÑов, ÑоздаваемÑÑ
Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÑнкÑии-конÑÑÑÑкÑоÑа. Ðозже Ð¼Ñ ÑаÑÑмоÑÑим, как можно иÑполÑзоваÑÑ ÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ.
ÐÑÑ Ð´Ð¾ÑÑаÑоÑно пÑоÑÑо. ÐÑделим оÑновнÑе моменÑÑ:
- СвойÑÑво
F.prototype(не пÑÑаÑÑ Ñ[[Prototype]]) ÑÑÑанавливаеÑ[[Prototype]]Ð´Ð»Ñ Ð½Ð¾Ð²ÑÑ Ð¾Ð±ÑекÑов пÑи вÑзовеnew F(). - ÐнаÑение
F.prototypeдолжно бÑÑÑ Ð»Ð¸Ð±Ð¾ обÑекÑом, либоnull. ÐÑÑгие знаÑÐµÐ½Ð¸Ñ Ð½Ðµ бÑдÑÑ ÑабоÑаÑÑ. - СвойÑÑво
"prototype"ÑвлÑеÑÑÑ Ð¾ÑобÑм, ÑолÑко когда оно назнаÑено ÑÑнкÑии-конÑÑÑÑкÑоÑÑ, коÑоÑÐ°Ñ Ð²ÑзÑваеÑÑÑ Ð¾Ð¿ÐµÑаÑоÑомnew.
РобÑÑнÑÑ
обÑекÑаÑ
prototype не ÑвлÑеÑÑÑ Ñем-Ñо оÑобеннÑм:
let user = {
name: "John",
prototype: "Bla-bla" // никакой магии Ð½ÐµÑ - обÑÑное ÑвойÑÑво
};
Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð²Ñе ÑÑнкÑии имеÑÑ F.prototype = { constructor: F }, поÑÑÐ¾Ð¼Ñ Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ полÑÑиÑÑ ÐºÐ¾Ð½ÑÑÑÑкÑÐ¾Ñ Ð¾Ð±ÑекÑа ÑеÑез ÑвойÑÑво "constructor".
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)