Prototypiske nedarvning i JavaScript

Original: http://javascript.crockford.com/prototypal.html

Douglas Crockford
www.crockford.com

For fem år siden skrev jeg klassisk nedarvning i JavaScript (kinesisk Italiensk Japansk). Den viste, at JavaScript er et klasse-fri, prototypal sprog, og at det har tilstrækkelig udtrykskraft til at simulere et klassisk system. Min programmering stil har udviklet sig siden da, som enhver god programmør burde. Jeg har lært at fuldt ud at omfavne prototypalism, og har befriet mig fra for rammerne af den klassiske model.

Min rejse var omstændelig, fordi JavaScript ikke selv er konflikt om sin prototypal natur. I et prototypal system objekter arver fra objekter. JavaScript, mangler imidlertid en operatør, der udfører operationen. I stedet har en ny operatør, således at

ny f ()

frembringer et nyt objekt, som arver fra

f.prototype

Denne indirection blev til formål at gøre sproget synes mere fortrolige med klassisk uddannet programmører, men undlod at gøre det, som vi kan se fra det meget lave udtalelse Java-programmører har JavaScript. JavaScripts konstruktør mønster ikke appellerer til den klassiske publikum. Det tilsløret også JavaScripts sande prototypal natur. Som et resultat, er der meget få programmører, der ved, hvordan man bruger sproget effektivt.

Heldigvis er det nemt at oprette en operatør, der implementerer ægte prototypal arv. Det er en standard funktion i min værktøjskasse, og jeg stærkt anbefale det til dit.

funktion objekt (o) {
Funktionen F () {}
F.prototype = o;
returnere nye F ();
}
Objektet funktion untangles JavaScripts konstruktør mønster, opnå ægte prototypal arv. Det tager en gammel objekt som en parameter og returnerer en tom nye objekt, der arver fra den gamle. Hvis vi forsøger at få et medlem fra det nye objekt, og det mangler denne nøgle, så den gamle objekt vil levere medlem. Objekter arver fra objekter. Hvad kunne være mere objektorienteret end det?

Så i stedet for at oprette klasser, du laver prototype objekter, og brug derefter det objekt funktion til at lave nye forekomster. Objekter er foranderlig i JavaScript, så vi kan øge de nye tilfælde, hvilket giver dem nye felter og metoder. Disse kan derefter fungere som prototyper til endnu nyere objekter. Vi har ikke brug klasser for at tjene masser af lignende genstande.

For nemheds skyld kan vi oprette funktioner, der vil kalde objektet funktion for os, og give andre tilpasninger, såsom at forstærke de nye objekter med privilegerede funktioner. Jeg har nogle gange kalder disse maker funktioner. Hvis vi har en maker funktion, der kalder en anden maker funktion i stedet for at kalde objektet funktion, så har vi en parasitisk arv mønster.

Jeg har fundet, at ved at bruge disse værktøjer, kombineret med JavaScripts lambdas og objekt kvasi-litteraler, jeg kan skrive velstrukturerede programmer, der er store, komplekse og effektive. Den klassiske objekt model er langt den mest populære i dag, men jeg tror, ​​at prototypal objekt model er mere i stand og byder på mere udtryksfuld magt.

At lære disse nye mønstre også gjort mig til en bedre klassisk programmør. Erfaringer fra den dynamiske verden kan have anvendelse i statisk.

2006-06-07

Her er en anden formulering:

Object.prototype.begetObject = function () {
Funktionen F () {}
F.prototype = dette;
returnere nye F ();
};

newObject = oldObject.begetObject ();
2007-04-02

Problemet med det formål funktion er, at det er globalt, og globals klart problematisk. Problemet med Object.prototype.begetObject er, at den kobler op inkompetente programmer, og det kan give uventede resultater, når begetObject tilsidesættes.

Så nu foretrækker jeg denne formulering:

if (typeof Object.create! == »funktion«) {
Object.create = funktion (o) {
Funktionen F () {}
F.prototype = o;
returnere nye F ();
};
}
newObject = Object.create (oldObject);
2008-04-07

Comments are closed.