Funcția Prototype Property

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.


De ce ai grija de prototip Proprietate?

Ar trebui să ai grijă de asta prototip proprietate din patru motive.

Motivul 1

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.

Motivul 2

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ă.

Motivul 3

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.

Motivul 4

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.

Prototipul este standard pe toate Funcţie() Instanțe

Toate 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.


Implicit prototip Proprietatea este un Obiect() Obiect

Toate 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ă.


Instanțele create de o funcție constructor sunt legate de constructor 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.


Ultima oprire în 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.


Înlocuirea prototip Proprietatea cu un obiect nou elimină proprietatea implicită a constructorului

Este 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

 

Încărcări de proprietăți din prototip Va primi întotdeauna cele mai recente valori

Proprietatea 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

 

Înlocuirea prototip Proprietatea cu un obiect nou nu actualizează fostele instanțe

S-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.

Constructorii definiti de utilizator pot folosi acelasi lucru prototip Moștenirea ca constructori nativi

Speră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

 

Crearea lanțurilor de moștenire (intenția inițială)

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

 

Concluzie

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.

Cod