prototip
proprietatea este un obiect creat de JavaScript pentru fiecare Funcţie()
instanță. Mai exact, el leagă instanțele create de obiecte nou
cuvinte cheie înapoi la funcția constructor care le-a creat. Acest lucru se face astfel încât instanțele să poată împărtăși sau moșteni metode și proprietăți comune. Este important faptul că partajarea are loc în timpul căutării proprietății. Rețineți din primul articol că de fiecare dată când căutați sau accesați o proprietate asupra unui obiect, proprietatea va fi căutată atât pe obiect, cât și pe lanțul prototip.
Un prototip este creat pentru fiecare funcție, indiferent dacă intenționați să utilizați această funcție ca constructor.
În următorul cod, construiesc o matrice din Array ()
constructor, și apoi invoc a adera()
metodă.
Mostră: sample118.html
a adera()
metoda nu este definită ca o proprietate a myArray
obiect, dar cumva avem acces la a adera()
ca și cum ar fi fost. Această metodă este definită undeva, dar unde? Ei bine, este definit ca o proprietate a Array ()
constructorul proprietate prototip. De cand a adera()
nu este găsit în instanța obiectului de matrice, JavaScript caută lanțul prototip pentru o metodă numită a adera()
.
Bine, deci de ce se fac lucrurile in acest fel? Într-adevăr, este vorba despre eficiență și reutilizare. De ce ar trebui ca fiecare instanță de tabelă creată din funcția constructorului array să fie definită în mod unic a adera()
atunci când a adera()
funcționează mereu în același mod? Este mai important ca toate matricele să folosească la fel a adera()
fără a trebui să creați o nouă instanță a funcției pentru fiecare instanță de matrice.
Această eficiență despre care vorbim este posibilă din cauza prototip
proprietatea, legătura prototip și lanțul de căutare prototip. În acest articol, defalcăm aceste atribute adesea confuze ale moștenirii prototipice. Dar, adevărul trebuie spus, veți fi mai bine prin memorarea pur și simplu a mecanismelor de funcționare a ierarhiei lanțului. Reveniți la primul articol dacă aveți nevoie de o reîmprospătare a modului în care sunt rezolvate valorile proprietăților.
prototip
Proprietate?Ar trebui să ai grijă de asta prototip
proprietate din patru motive.
Primul motiv este că proprietatea prototip este folosită de funcțiile constructorului nativ (Obiect()
, Array ()
, Funcţie()
, etc.) pentru a permite instanțelor constructorului să moștenească proprietățile și metodele. Este mecanismul pe care JavaScript îl folosește pentru a permite instanțelor de obiecte să moștenească proprietățile și metodele din funcțiile constructorului prototip
proprietate. Dacă doriți să înțelegeți mai bine JavaScript, trebuie să înțelegeți cum se utilizează JavaScript însuși prototip
obiect.
Atunci când creați funcții constructor definite de utilizator, puteți orchestra mostenirea în același mod în care fac obiectele native JavaScript. Dar mai întâi trebuie să înveți cum funcționează.
S-ar putea să nu vă plac moștenirea prototypală sau să preferați un alt model pentru moștenirea obiectului, dar realitatea este că într-o zi ar trebui să editați sau să gestionați codul altcuiva care crede că moștenirea prototypală a fost genunchii albinelor. Când se întâmplă acest lucru, ar trebui să fii conștient de modul în care funcționează moștenirea prototypală, precum și de modul în care poate fi replicat de dezvoltatorii care folosesc funcțiile constructorului personalizat.
Prin utilizarea moștenirii prototip, puteți crea instanțe eficiente de obiect care utilizează toate aceleași metode. Așa cum am menționat deja, nu toate obiectele matrice, care sunt instanțe ale Array ()
constructor, au nevoie de propriile lor a adera()
metode. Toate situațiile pot avea același efect a adera()
deoarece metoda este stocată în lanțul prototip.
Funcţie()
InstanțeToate funcțiile sunt create din a Funcţie()
constructor, chiar dacă nu îl invocați în mod direct Funcţie()
constructor (var add = new Funcție ('x', 'y', 'return x + z');
) și folosiți în schimb notația literală (var add = funcția (x, y) return x + z;
).
Atunci când este creată o instanță de funcții, aceasta este întotdeauna dată a prototip
proprietate, care este un obiect gol. În exemplul următor, definim o funcție numită myFunction și apoi accesăm prototip
proprietate care este pur și simplu un obiect gol.
Mostră: sample119.html
Asigurați-vă că înțelegeți complet că proprietatea prototipului vine de la Funcţie()
constructor. Numai o dată intenționăm să folosim funcția noastră ca funcție de constructor definită de utilizator, că proprietatea prototipului este influențată de levier, dar acest lucru nu schimbă faptul că Funcţie()
constructor dă fiecare instanță o proprietate prototip.
prototip
Proprietatea este un Obiect()
ObiectToate acestea prototip
vorbesc poate fi cam greu. Cu adevărat, prototip
este doar o proprietate obiect gol numit "prototip" creat în spatele scenei de către JavaScript și pus la dispoziție prin invocarea Funcţie()
constructor. Dacă ați fi făcut-o manual, ar arăta astfel:
Mostră: sample120.html
De fapt, acest exemplu de cod funcționează foarte bine, în esență, doar duplicând ceea ce face JavaScript.
Valoarea unei proprietăți prototip poate fi setată la oricare dintre valorile complexe (obiecte) disponibile în JavaScript. JavaScript va ignora orice proprietate prototip setată la o valoare primitivă.
prototip
ProprietateÎn timp ce singurul său obiect, prototip
este special deoarece lanțul prototip leagă fiecare instanță de proprietatea prototipului funcției constructorului. Aceasta inseamna ca oricand un obiect este creat dintr-o functie constructor folosind nou
(sau atunci când un wrapper de obiecte este creat pentru o valoare primitivă), adaugă o legătură ascunsă între instanța obiectului creată și proprietatea prototip a funcției constructor utilizate pentru crearea acesteia. Această legătură este cunoscută în interiorul instanței ca __proto__
(deși este expus / acceptat numai prin intermediul codului în Firefox 2+, Safari, Chrome și Android). JavaScript rulează acest lucru împreună în fundal atunci când este invocată o funcție de constructor și această legătură care permite lanțului prototip să fie, bine, un lanț. În exemplul următor, adăugăm o proprietate la nativ Array ()
constructori prototip
, pe care le putem accesa apoi de la Array ()
instanță folosind __proto__
proprietate stabilită pe acea instanță.
Mostră: sample121.html
De la accesare __proto__
nu face parte din standardul ECMA oficial, există un mod mai universal de urmărire a legăturii de la un obiect la prototipul obiect pe care îl moștenește, și anume prin utilizarea constructor
proprietate. Acest lucru este demonstrat în următorul eșantion.
Mostră: sample122.html
În acest exemplu, foo
proprietatea se găsește în obiectul prototip. Trebuie să vă dați seama că acest lucru este posibil numai din cauza asocierii dintre instanța Array ()
si Array ()
constructor prototip (Array.prototype
). Pur și simplu pune, myArray .__ proto__
(sau myArray.constructor.prototype
) Array.prototype
.
prototip
Lanțul este Object.prototype
Deoarece proprietatea prototipului este un obiect, ultima oprire din lanțul prototip sau de căutare este la Object.prototype
. În codul care urmează, eu creez myArray
, care este o matrice goală. Apoi încerc să accesez o proprietate a myArray
care nu a fost încă definită, implicând lanțul de căutare prototip. myArray
obiect este examinat pentru proprietatea foo. Fiind absent, proprietatea este căutată Array.prototype
, dar nu este nici acolo. Deci, locul final JavaScript pare Object.prototype
. Deoarece nu este definită în nici unul dintre aceste trei obiecte, proprietatea este nedefinit
.
Mostră: sample123.html
Luați notă că lanțul sa oprit Object.prototype
. Ultimul loc pe care l-am căutat era foo Object.prototype
.
Atent! Orice adăugat la Object.prototype se va afișa într-o buclă pentru.
prototip
Lanțul returnează prima potrivire a proprietății pe care o găsește în lanțCa și lanțul de domeniu, prototip
lanțul va folosi prima valoare pe care o găsește în timpul căutării în lanț.
Modificarea exemplului de cod anterior, dacă am adăugat aceeași valoare pentru Object.prototype
și Array.prototype
obiecte și apoi încercat să acceseze o valoare într-o instanță de array, valoarea returnată ar fi de la Array.prototype
obiect.
Mostră: sample124.html
În această probă, valoarea foo la Array.prototype.foo
este umbrirea sau mascarea foo
valoare găsită la Object.prototype.foo
. Amintiți-vă că căutarea se termină atunci când proprietatea se găsește în lanț, chiar dacă același nume de proprietate este folosit și mai departe în sus.
prototip
Proprietatea cu un obiect nou elimină proprietatea implicită a constructoruluiEste posibil să înlocuiți valoarea implicită a prototip
proprietate cu o valoare nouă. Cu toate acestea, acest lucru va elimina proprietatea constructorului implicit găsit în "pre-made" prototip
obiect dacă nu specificați manual unul.
În codul care urmează, creăm a foo
constructor funcția, înlocuiți prototip
proprietatea cu un nou obiect gol și verificați dacă proprietatea constructorului este ruptă (se referă acum la cele mai puțin utile Obiect
prototip).
Mostră: sample125.html
Dacă intenționați să înlocuiți setarea implicită prototip
proprietate (comună cu unele modele JS OOP) configurate de JavaScript, trebuie să conectați împreună o proprietate a constructorului care face referire la funcția constructorului. În exemplul următor, ne modificăm codul anterior, astfel încât constructor
proprietatea va oferi din nou o referință la funcția corectă a constructorului.
Mostră: sample126.html
prototip
Va primi întotdeauna cele mai recente valoriProprietatea prototip este dinamică, în sensul că instanțele vor primi întotdeauna cea mai recentă valoare din prototip, indiferent de momentul în care a fost instanțiată, modificată sau anexată. În codul care urmează, creăm a foo
constructor, adăugați proprietatea X
la prototip
, și apoi să creați o instanță de Foo ()
numit FooInstance
. Apoi, se înregistrează valoarea lui X
. Apoi actualizăm valoarea prototipurilor lui x și îl logăm din nou pentru a afla că instanța noastră are acces la cea mai recentă valoare găsită în prototip
obiect.
Mostră: sample127.html
Având în vedere modul în care lanțul de căutare funcționează, acest comportament nu ar trebui să fie atât de surprinzător. Dacă vă întrebați, acest lucru funcționează la fel, indiferent dacă utilizați implicit prototip
obiect sau suprascrie-l cu al tău. În următorul eșantion, înlocuiesc setarea implicită prototip
obiect pentru a demonstra acest fapt.
Mostră: sample128.html
prototip
Proprietatea cu un obiect nou nu actualizează fostele instanțeS-ar putea să credeți că puteți înlocui prototip
proprietate în întregime în orice moment și că toate instanțele vor fi actualizate, dar acest lucru nu este corect. Când creați o instanță, acea instanță va fi legată de prototip
care a fost bătut la momentul instanței. Furnizarea unui obiect nou ca proprietate prototip nu actualizează conexiunea dintre instanțele deja create și cea nouă prototip
.
Dar rețineți, după cum am spus anterior, puteți să actualizați sau să adăugați la cele create inițial prototip
obiect și aceste valori rămân conectate la prima instanță (e).
Mostră: sample129.html
Ideea cheie care trebuie luată aici este că un prototip de obiecte nu ar trebui înlocuit cu un obiect nou odată ce începeți să creați instanțe. Acest lucru va duce la instanțe care au o legătură cu diferite prototipuri.
prototip
Moștenirea ca constructori nativiSperăm că în acest moment în articol se scufundă în modul în care JavaScript însuși folosește prototip
proprietate pentru moștenire (Array.prototype
). Același model poate fi utilizat la crearea unor funcții constructor non-native, definite de utilizator. În exemplul următor, luăm clasicul Persoană
obiect și să imite modelul pe care JavaScript îl folosește pentru moștenire.
Mostră: sample130.html
În acest cod, a Persoană()
este creată funcția constructor. Apoi adăugăm proprietăți la prototip
proprietatea Persoană()
, care pot fi moștenite de toate instanțele. În mod clar, puteți utiliza lanțul prototip în codul dvs. în același mod în care JavaScript îl folosește pentru moștenirea obiectului nativ.
Ca un exemplu bun în ceea ce privește modul în care puteți influența acest lucru, puteți crea o funcție a constructorului a cărei instanță moștenesc picioare
și arme
dacă nu sunt furnizate ca parametri. În următorul eșantion, dacă Persoană()
constructorul este trimis parametri, parametrii sunt utilizați ca proprietăți de instanță, dar dacă unul sau mai mulți parametri nu sunt furnizați, există o schimbare. Aceste proprietăți de instanță atunci umbresc sau maschează proprietățile moștenite, oferindu-vă cele mai bune din ambele lumi.
Mostră: sample131.html
Moștenirea prototopică a fost concepută pentru a permite lanturi de moștenire care imită modelele de mostenire găsite în limbile de programare orientate obiect tradițional. Pentru ca un obiect să moștenească de la un alt obiect în JavaScript, tot ce trebuie să faceți este să instanțiați o instanță a obiectului pe care doriți să-l moșteniți și să îl atribuiți prototip
proprietatea obiectului care face moștenirea.
În eșantionul de cod care urmează, bucătar-șef
obiecte (cody
) moștenire de la Persoană()
. Aceasta înseamnă că dacă o proprietate nu este găsită într-o bucătar-șef
obiect, acesta va fi apoi căutat pe prototipul funcției create Persoană()
obiecte. Pentru a sârmă moștenirea, tot ce trebuie să faceți este să instanțiați o instanță Persoană()
ca valoare pentru Chef.prototype
(Chef.prototype = persoană nouă ();
).
Mostră: sample132.html
Tot ce am făcut în această probă a fost un sistem care a fost deja în vigoare cu obiectele native. Consider că Persoană()
nu este diferit de implicit Obiect()
pentru proprietățile prototipului. Cu alte cuvinte, acesta este exact ceea ce se întâmplă atunci când o proprietate prototip, care conține implicit gol Obiect()
valoare, se uită la prototipul funcției constructor create (Object.prototype
) pentru proprietăți moștenite.