ÐлаÑÑивÑÑÑÑ "prototype" ÑиÑоко викоÑиÑÑовÑÑÑÑÑÑ ÑдÑом Ñамого JavaScript. ÐÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑÑÑÑ Ð²ÑÑ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ñ ÑÑнкÑÑÑ ÐºÐ¾Ð½ÑÑÑÑкÑоÑа.
СпоÑаÑÐºÑ Ð¼Ð¸ ÑозглÑнемо деÑалÑ, а поÑÑм ÑозбеÑемоÑÑ Ñк додаÑи Ð½Ð¾Ð²Ð¸Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ÑÑей вбÑдованим обâÑкÑам.
Object.prototype
СкажÑмо, ми виводимо поÑожнÑй обâÑкÑ:
let obj = {};
alert( obj ); // "[object Object]" ?
Ðе код, Ñкий генеÑÑÑ ÑÑдок "[object Object]"? Це вбÑдований меÑод toString, але де Ñе? obj поÑожнÑй!
â¦Ð°Ð»Ðµ коÑоÑке познаÑÐµÐ½Ð½Ñ obj = {} â Ñе Ñе Ñаме, Ñо obj = new Object(), де Object Ñ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ð¾Ñ ÑÑнкÑÑÑÑ-конÑÑÑÑкÑоÑом обâÑкÑа, з влаÑним prototype, Ñо поÑилаÑÑÑÑÑ Ð½Ð° велиÑезний обâÑÐºÑ Ð· toString Ñа ÑнÑими меÑодами.
ÐÑÑ Ñо вÑдбÑваÑÑÑÑÑ:
Ðоли викликаÑÑÑÑÑ new Object() (або ÑÑвоÑÑÑÑÑÑÑ Ð»ÑÑеÑалÑний обâÑÐºÑ {...}), Ñ Ð²Ð»Ð°ÑÑивÑÑÑÑ [[Prototype]] вÑÑановлÑÑÑÑÑÑ Object.prototype згÑдно з пÑавилом, Ñке ми обговоÑÑвали Ñ Ð¿Ð¾Ð¿ÐµÑеднÑÐ¾Ð¼Ñ ÑоздÑлÑ:
ÐÑже, коли викликаÑÑÑÑÑ obj.toString(), Ñей меÑод беÑеÑÑÑÑ Ð· Object.prototype.
Ðи можемо пеÑевÑÑиÑи Ñе Ñак:
let obj = {};
alert(obj.__proto__ === Object.prototype); // true
alert(obj.toString === obj.__proto__.toString); //true
alert(obj.toString === Object.prototype.toString); //true
ÐÑÐ´Ñ Ð»Ð°Ñка, звеÑнÑÑÑ ÑвагÑ, Ñо бÑлÑÑе Ð½ÐµÐ¼Ð°Ñ [[Prototype]] Ñ Ð»Ð°Ð½ÑÑÐ³Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÑв над Object.prototype:
alert(Object.prototype.__proto__); // null
ÐнÑÑ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ñ Ð¿ÑоÑоÑипи
ÐнÑÑ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ñ Ð¾Ð±âÑкÑи, ÑÐ°ÐºÑ Ñк Array, Date, Function Ñа ÑнÑÑ Ñакож збеÑÑгаÑÑÑ Ð¼ÐµÑоди Ñ Ð¿ÑоÑоÑипаÑ
.
ÐапÑиклад, коли ми ÑÑвоÑÑÑмо маÑив [1, 2, 3], внÑÑÑÑÑнÑо викоÑиÑÑовÑÑÑÑÑÑ ÐºÐ¾Ð½ÑÑÑÑкÑÐ¾Ñ new Array(). Таким Ñином Array.prototype ÑÑÐ°Ñ Ð¹Ð¾Ð³Ð¾ пÑоÑоÑипом Ñ Ð½Ð°Ð´Ð°Ñ ÑÐ²Ð¾Ñ Ð¼ÐµÑоди. Це дÑже еÑекÑивно.
Ðа ÑпеÑиÑÑкаÑÑÑÑ, на веÑÑÐ¸Ð½Ñ ÑÑÑаÑÑ
ÑÑ Ð²ÑÑ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ñ Ð¿ÑоÑоÑипи маÑÑÑ Object.prototype. ÐÑÑ ÑÐ¾Ð¼Ñ Ð´ÐµÑÐºÑ Ð»Ñди кажÑÑÑ, Ñо âвÑе ÑÑпадковÑÑÑÑÑÑ Ð²Ñд обâÑкÑÑвâ.
ÐÑÑ Ð·Ð°Ð³Ð°Ð»Ñна каÑÑина (Ð´Ð»Ñ 3 вбÑÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð±âÑкÑÑв):
ÐеÑевÑÑмо пÑоÑоÑипи вÑÑÑнÑ:
let arr = [1, 2, 3];
// arr ÑÑпадковÑÑÑÑÑÑ Ð²Ñд Array.prototype?
alert( arr.__proto__ === Array.prototype ); // true
// поÑÑм вÑд Object.prototype?
alert( arr.__proto__.__proto__ === Object.prototype ); // true
// Ñ null на веÑÑинÑ.
alert( arr.__proto__.__proto__.__proto__ ); // null
ÐеÑÐºÑ Ð¼ÐµÑоди в пÑоÑоÑипаÑ
можÑÑÑ Ð¿ÐµÑекÑиваÑиÑÑ, напÑиклад, Array.prototype Ð¼Ð°Ñ ÑвÑй влаÑний toString, Ñкий пеÑелÑÑÑÑ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи ÑоздÑÐ»ÐµÐ½Ñ ÐºÐ¾Ð¼Ð°Ð¼Ð¸:
let arr = [1, 2, 3]
alert(arr); // 1,2,3 <-- ÑезÑлÑÑÐ°Ñ Array.prototype.toString
Як ми баÑили ÑанÑÑе, Object.prototype Ñакож Ð¼Ð°Ñ toString, але Array.prototype ближÑе по ланÑÑÐ³Ñ Ð¿ÑоÑоÑипÑв, ÑÐ¾Ð¼Ñ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑÑÑÑÑÑ Ð²Ð°ÑÑÐ°Ð½Ñ Ð¼Ð°ÑивÑ.
ÐнÑÑÑÑменÑи бÑаÑзеÑа, ÑÐ°ÐºÑ Ñк конÑÐ¾Ð»Ñ ÑозÑобника Chrome, Ñакож показÑÑÑÑ Ð½Ð°ÑлÑдÑÐ²Ð°Ð½Ð½Ñ (можливо, доведеÑÑÑÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑваÑи console.dir Ð´Ð»Ñ Ð²Ð±ÑдованиÑ
обâÑкÑÑв):
ÐнÑÑ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ñ Ð¾Ð±âÑкÑи Ñакож пÑаÑÑÑÑÑ Ñак Ñамо. ÐавÑÑÑ ÑÑнкÑÑÑ â вони Ñ Ð¾Ð±âÑкÑами вбÑдованого конÑÑÑÑкÑоÑа Function, а ÑÑ
Ð½Ñ Ð¼ÐµÑоди (call/apply Ñа ÑнÑÑ) беÑÑÑÑÑÑ Ð· Function.prototype. ФÑнкÑÑÑ Ð¼Ð°ÑÑÑ Ð²Ð»Ð°ÑÐ½Ñ toString.
function f() {}
alert(f.__proto__ == Function.prototype); // true
alert(f.__proto__.__proto__ == Object.prototype); // true, ÑÑпадковÑÑÑÑÑÑ Ð²Ñд обâÑкÑÑв
ÐÑимÑÑиви
ÐайÑкладнÑÑа ÑÑÑ Ð²ÑдбÑваÑÑÑÑÑ Ð· ÑÑдками, ÑиÑлами Ñа бÑлÑовими знаÑеннÑми.
Як ми памâÑÑаÑмо, вони не Ñ Ð¾Ð±âÑкÑами. Ðле ÑкÑо ми ÑпÑобÑÑмо оÑÑимаÑи доÑÑÑп до ÑÑ
влаÑÑивоÑÑей, ÑÑвоÑÑÑÑÑÑÑ ÑимÑаÑÐ¾Ð²Ñ Ð¾Ð±âÑкÑи-обгоÑÑки, викоÑиÑÑовÑÑÑи вбÑÐ´Ð¾Ð²Ð°Ð½Ñ ÐºÐ¾Ð½ÑÑÑÑкÑоÑи String, Number Ñа Boolean. Ðони забезпеÑÑÑÑÑ Ð¼ÐµÑоди, а пÑÑÐ»Ñ ÑÑого зникаÑÑÑ.
Ð¦Ñ Ð¾Ð±âÑкÑи ÑÑвоÑÑÑÑÑÑÑ Ð¿ÑиÑ
овано вÑд наÑ, Ñ Ð±ÑлÑÑÑÑÑÑ ÑÑÑÑÑв опÑимÑзÑÑÑÑ ÑÑ
, але ÑпеÑиÑÑкаÑÑÑ Ð¾Ð¿Ð¸ÑÑÑ Ñе Ñаме Ñаким Ñином. ÐеÑоди ÑиÑ
обâÑкÑÑв Ñакож знаÑ
одÑÑÑÑÑ Ñ Ð¿ÑоÑоÑипаÑ
, доÑÑÑпниÑ
Ñк String.prototype, Number.prototype Ñа Boolean.prototype.
null Ñа undefined не маÑÑÑ Ð¶Ð¾Ð´Ð½Ð¸Ñ
обâÑкÑÑв-обгоÑÑокСпеÑÑалÑÐ½Ñ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ null Ñа undefined ÑÑоÑÑÑ Ð¾ÐºÑемо. Ðони не маÑÑÑ Ð¾Ð±âÑкÑÑв-обгоÑÑок, ÑÐ¾Ð¼Ñ Ð´Ð»Ñ Ð½Ð¸Ñ
недоÑÑÑÐ¿Ð½Ñ Ð¼ÐµÑоди Ñа влаÑÑивоÑÑÑ. Рвони Ñакож не маÑÑÑ Ð²ÑдповÑдниÑ
пÑоÑоÑипÑв.
ÐмÑна вбÑÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑоÑоÑипÑв
ÐбÑÐ´Ð¾Ð²Ð°Ð½Ñ Ð¿ÑоÑоÑипи можÑÑÑ Ð±ÑÑи змÑненÑ. ÐапÑиклад, ÑкÑо додаÑи меÑод до String.prototype, вÑн ÑÑÐ°Ñ Ð´Ð¾ÑÑÑпним Ð´Ð»Ñ Ð²ÑÑÑ
ÑÑдкÑв:
String.prototype.show = function() {
alert(this);
};
"ÐУÐ!".show(); // ÐУÐ!
ÐÑд ÑÐ°Ñ ÑозÑобки ми можемо маÑи ÑÐ´ÐµÑ Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¼ÐµÑодÑв, ÑÐºÑ Ð¼Ð¸ Ñ Ð¾ÑÑли б маÑи, Ñ Ð¼Ð¸ можемо маÑи ÑпокÑÑÑ Ð´Ð¾Ð´Ð°Ñи ÑÑ Ð´Ð¾ вбÑÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑоÑоÑипÑв. Ðле Ñе, Ñк пÑавило, погана ÑдеÑ.
ÐÑоÑоÑипи Ñ Ð³Ð»Ð¾Ð±Ð°Ð»Ñними, ÑÐ¾Ð¼Ñ Ñак можна легко оÑÑимаÑи конÑлÑкÑ. ЯкÑо Ð´Ð²Ñ Ð±ÑблÑоÑеки додаÑÑÑ Ð¼ÐµÑод String.prototype.show, Ñо один з ниÑ
бÑде пеÑезапиÑаний ÑнÑим.
ÐÑже, загалом, модиÑÑкаÑÑÑ Ð²Ð±Ñдованого пÑоÑоÑÐ¸Ð¿Ñ Ð²Ð²Ð°Ð¶Ð°ÑÑÑÑÑ Ð¿Ð¾Ð³Ð°Ð½Ð¾Ñ ÑдеÑÑ.
У ÑÑÑаÑÐ½Ð¾Ð¼Ñ Ð¿ÑогÑамÑÐ²Ð°Ð½Ð½Ñ ÑÑнÑÑ Ð»Ð¸Ñе один випадок, коли заÑвеÑджÑÑÑÑÑÑ Ð¼Ð¾Ð´Ð¸ÑÑкаÑÑÑ ÑÑÐ´Ð½Ð¸Ñ Ð¿ÑоÑоÑипÑв. Це ÑÑвоÑÐµÐ½Ð½Ñ Ð¿Ð¾Ð»ÑÑÑлÑв.
ÐолÑÑÑл â Ñе ÑеÑмÑн, Ñо ознаÑÐ°Ñ Ð·Ð°Ð¼ÑÐ½Ñ Ð¼ÐµÑодÑ, Ñкий ÑÑнÑÑ Ð² ÑпеÑиÑÑкаÑÑÑ JavaScript, але Ñе не пÑдÑÑимÑÑÑÑÑÑ Ð¿ÐµÐ²Ð½Ð¸Ð¼ ÑÑÑÑÑм JavaScript.
Ð¢Ð¾Ð´Ñ Ð¼Ð¸ можемо ÑеалÑзÑваÑи його вÑÑÑÐ½Ñ Ñа заповниÑи вбÑдований пÑоÑоÑип ним.
ÐапÑиклад:
if (!String.prototype.repeat) { // ÑкÑо Ñакого меÑÐ¾Ð´Ñ Ð½ÐµÐ¼Ð°Ñ
// додайÑе його до пÑоÑоÑипÑ
String.prototype.repeat = function(n) {
// повÑоÑÑÑÑ ÑÑдок n ÑазÑв
// наÑпÑавдÑ, код повинен бÑÑи ÑÑоÑ
и ÑкладнÑÑим
// (повний алгоÑиÑм можна знайÑи в ÑпеÑиÑÑкаÑÑÑ)
// але навÑÑÑ Ð½ÐµÐ´Ð¾Ñконалий полÑÑÑл ÑаÑÑо вважаÑÑÑÑÑ Ð¿ÑийнÑÑним Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾ÑиÑÑаннÑ
return new Array(n + 1).join(this);
};
}
alert( "Ðа".repeat(3) ); // ÐаÐаÐа
ÐапозиÑÐµÐ½Ð½Ñ Ð· пÑоÑоÑипÑв
У ÑоздÑÐ»Ñ ÐекоÑаÑоÑи Ñа пеÑеадÑеÑаÑÑÑ Ð²Ð¸ÐºÐ»Ð¸ÐºÑ, call/apply ми говоÑили пÑо запозиÑÐµÐ½Ð½Ð½Ñ Ð¼ÐµÑодÑв.
Це коли ми пÑиймаÑмо меÑод вÑд одного обâÑкÑа Ñ ÐºÐ¾Ð¿ÑÑÑмо його в ÑнÑий.
ÐеÑÐºÑ Ð¼ÐµÑоди вбÑÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑоÑоÑипÑв ÑаÑÑо позиÑаÑÑÑÑÑ.
ÐапÑиклад, ÑкÑо ми ÑÑвоÑимо обâÑкÑ, подÑбний до маÑивÑ, ми можемо ÑкопÑÑваÑи деÑÐºÑ Ð¼ÐµÑоди Array до нÑого.
ÐÑиклад:
let obj = {
0: "ÐÑивÑÑ",
1: "ÑвÑÑ!",
length: 2,
};
obj.join = Array.prototype.join;
alert( obj.join(',') ); // ÐÑивÑÑ,ÑвÑÑ!
Це пÑаÑÑÑ, оÑкÑлÑки Ð´Ð»Ñ Ð²Ð½ÑÑÑÑÑнÑого алгоÑиÑÐ¼Ñ Ð²Ð±Ñдованого меÑÐ¾Ð´Ñ join Ð²Ð°Ð¶Ð»Ð¸Ð²Ñ ÑÑлÑки пÑавилÑÐ½Ñ ÑндекÑи Ñа влаÑÑивÑÑÑÑ length. Це меÑод не пеÑевÑÑÑÑ, Ñи дÑйÑно обâÑÐºÑ Ñ Ð¼Ð°Ñивом. ÐагаÑо вбÑдованиÑ
меÑодÑв пÑаÑÑÑÑÑ Ð¿Ð¾Ð´Ñбним Ñином.
Ще одна можливÑÑÑÑ Ð¿Ð¾Ð»ÑÐ³Ð°Ñ Ð² ÑомÑ, Ñоб ÑÑпадкÑваÑиÑÑ Ð²Ñд маÑивÑ, вÑÑановлÑÑÑи obj.__ proto__ Ñк Array.prototype, Ñаким Ñином вÑÑ Ð¼ÐµÑоди Array авÑомаÑиÑно бÑдÑÑÑ Ð´Ð¾ÑÑÑÐ¿Ð½Ñ Ð² obj.
Ðле Ñе неможливо, ÑкÑо obj вже ÑÑпадковÑÑÑÑÑÑ Ð²Ñд ÑнÑого обâÑкÑа. ÐамâÑÑайÑе, Ñо ми не можемо ÑÑпадковÑваÑиÑÑ Ð²Ñд декÑлÑкоÑ
обâÑкÑÑв одноÑаÑно.
ÐапозиÑÐµÐ½Ð½Ñ Ð¼ÐµÑодÑв Ñ Ð³Ð½ÑÑкими, воно дозволÑÑ Ð·Ð¼ÑÑÑваÑи ÑÑнкÑÑоналÑнÑÑÑÑ ÑÑÐ·Ð½Ð¸Ñ Ð¾Ð±âÑкÑÑв, ÑкÑо Ñе Ð½ÐµÐ¾Ð±Ñ Ñдно.
ÐÑдÑÑмки
- ÐÑÑ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ñ Ð¾Ð±âÑкÑи ÑлÑдÑÑÑÑ Ð¾Ð´Ð½Ð°ÐºÐ¾Ð²Ð¾Ð¼Ñ ÑаблонÑ:
- ÐеÑоди збеÑÑгаÑÑÑÑÑ Ñ Ð¿ÑоÑоÑÐ¸Ð¿Ñ (
Array.prototype,Object.prototype,Date.prototypeÑа Ñн.). - Сам обâÑÐºÑ Ð·Ð±ÐµÑÑÐ³Ð°Ñ Ð»Ð¸Ñе Ð´Ð°Ð½Ñ (елеменÑи маÑивÑ, влаÑÑивоÑÑÑ Ð¾Ð±âÑкÑа, даÑÑ).
- ÐеÑоди збеÑÑгаÑÑÑÑÑ Ñ Ð¿ÑоÑоÑÐ¸Ð¿Ñ (
- ÐÑимÑÑиви Ñакож збеÑÑгаÑÑÑ Ð¼ÐµÑоди Ñ Ð¿ÑоÑоÑипаÑ
обâÑкÑÑв-обгоÑÑок:
Number.prototype,String.prototypeandBoolean.prototype. ТÑлÑкиundefinedÑаnullне маÑÑÑ Ð¾Ð±âÑкÑÑв-обгоÑÑок. - ÐбÑÐ´Ð¾Ð²Ð°Ð½Ñ Ð¿ÑоÑоÑипи можÑÑÑ Ð±ÑÑи змÑÐ½ÐµÐ½Ñ Ð°Ð±Ð¾ Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ñ Ð½Ð¾Ð²Ð¸Ð¼Ð¸ меÑодами. Ðле ÑÑ Ð½Ðµ ÑекомендÑÑÑÑÑÑ Ð·Ð¼ÑнÑваÑи. Ðдиний допÑÑÑимий випадок, мабÑÑÑ, коли ми додаÑмо ÑкийÑÑ Ð½Ð¾Ð²Ð¸Ð¹ ÑÑандаÑÑ, коÑÑий Ñе не пÑдÑÑимÑÑÑÑÑÑ ÑÑÑÑÑм JavaScript
ÐоменÑаÑÑ
<code>, Ð´Ð»Ñ ÐºÑлÑÐºÐ¾Ñ ÑÑдкÑв â обгоÑнÑÑÑ ÑÑ Ñегом<pre>, Ð´Ð»Ñ Ð¿Ð¾Ð½Ð°Ð´ 10 ÑÑдкÑв â викоÑиÑÑовÑйÑе пÑÑоÑниÑÑ (plnkr, jsbin, codepenâ¦)