Du husker nok at nye objekter kan oprettes med en konstruktr funktion, som f.eks. new F().
Hvis F.prototype er et objekt, s bruger new-operatoren det til at stte [[Prototype]] for det nye objekt.
JavaScript har haft nedarvning fra prototype fra begyndelsen. Det er en af sprogets kernetrk.
Men i gamle dage var der ikke nogen direkte adgang til det. Den eneste ting der virkede plideligt var en "prototype" egenskab i konstruktr funktioner som vi beskriver i dette kapitel. S der er mange scripts der stadig bruger denne tilgang.
Bemrk at udtrykket F.prototype her betyder en regulr egenskab kaldet "prototype" p objektet F. Det lyder som noget tt p selve begrebet prototype, men her mener vi faktisk bare en regulr egenskab med det navn.
Her er et eksempel:
let animal = {
eats: true
};
function Rabbit(name) {
this.name = name;
}
Rabbit.prototype = animal;
let rabbit = new Rabbit("Hvid kanin"); // rabbit.__proto__ == animal
alert( rabbit.eats ); // true
Nr vi skriver Rabbit.prototype = animal betyder det bogstaveligt talt: Nr en ny Rabbit skabes, s srg for at dens [[Prototype]] sttes til animal.
Det resulterer i flgende:
P billedet er "prototype" en horisontal pil, hvilket betyder en regulr egenskab, og [[Prototype]] er en lodret pil, betyder nedarvning af rabbit fra animal.
F.prototype bruges kun ved new FEgenskaben F.prototype bruges kun nr new F kaldes, og den stter [[Prototype]] p det nye objekt.
Hvis F.prototype-egenskaben ndres efter objektet er skabt (F.prototype = <another object>), s vil nye objekter skabt med new F have et andet objekt som [[Prototype]], mens eksisterende objekter beholder det gamle.
Standard F.prototype, konstruktr egenskab
Alle funktioner har egenskaben "prototype" selvom vi ikke angiver den.
Den standard "prototype" er et objekt med den ene egenskab constructor som peger tilbage p funktionen selv.
Som dette:
function Rabbit() {}
/* standard prototype
Rabbit.prototype = { constructor: Rabbit };
*/
Det kan vi tjekke ved at se p constructor egenskaben:
function Rabbit() {}
// som standard:
// Rabbit.prototype = { constructor: Rabbit }
alert( Rabbit.prototype.constructor == Rabbit ); // true
Hvis vi ikke gr noget andet vil egenskaben constructor vre tilgngelig for alle kaniner gennem [[Prototype]]:
function Rabbit() {}
// som standard:
// Rabbit.prototype = { constructor: Rabbit }
let rabbit = new Rabbit(); // nedarver fra {constructor: Rabbit}
alert(rabbit.constructor == Rabbit); // true (fra prototype)
Vi kan bruge constructor egenskaben til at skabe et nyt objekt med samme konstruktr som det eksisterende objekt.
Som her:
function Rabbit(name) {
this.name = name;
alert(name);
}
let rabbit = new Rabbit("Hvid kanin");
let rabbit2 = new rabbit.constructor("Sort kanin");
Det er praktisk nr vi har et objekt og ikke ved hvilken konstruktr det blev skabt med (f.eks. hvis det kommer fra en 3rd party bibliotek), og vi skal skabe et andet objekt af samme type.
Men den vigtigste ting at huske p om "constructor" er at
JavaScript sikrer ikke selv at vrdien i "constructor" er korrekt.
Ja, den eksisterer i standard "prototype" for funktioner, men det er det. Hvad der sker senere det er helt op til os.
Det glder srligt, hvis vi erstatter standard prototypen i sin helhed, s vil der ikke lngere vre nogen "constructor" i den.
For eksempel:
function Rabbit() {}
Rabbit.prototype = {
jumps: true
};
let rabbit = new Rabbit();
alert(rabbit.constructor === Rabbit); // false
S for at beholde den korrekte "constructor" kan vi vlge at tilfje/fjerne egenskaber til standard "prototype" i stedet for at overskrive hele prototypen:
function Rabbit() {}
// Overskriver ikke Rabbit.prototype helt
// vi tilfjer bare noget til den
Rabbit.prototype.jumps = true
// standard Rabbit.prototype.constructor er bevaret
Alternativt kan du genskabe egenskaben constructor manuelt, hvis du erstatter hele prototypen:
Rabbit.prototype = {
jumps: true,
constructor: Rabbit
};
// nu er constructor rigtig igen, fordi vi tilfjede den tilbage til objektet
Opsummering
I dette kapitel beskrev vi kort mden at stte en [[Prototype]] for objekter skabt via en konstruktr funktion. Senere vil vi se mere avancerede programmeringsmnstre, der bygger p det.
Alt er egentlig ganske enkelt. Her er nogle f bemrkninger for at gre tingene helt klart:
- Egenskaben
F.prototype(ikke at forveksle med[[Prototype]]) stter[[Prototype]]p nye objekter nrnew F()kaldes. - Vrdien af
F.prototypebr enten vre et objekt ellernull: andre vrdier virker ikke. - Egenskaben
"prototype"har kun denne specielle effekt nr den er sat p en konstruktr funktion, og kaldes mednew.
P regulre objekter er prototype ikke noget specielt:
let user = {
name: "John",
prototype: "Bla-bla" // magien er vk!
};
Som standard har alle funktioner F.prototype = { constructor: F }, s vi kan f konstruktren af et objekt ved at tilg dets "constructor" egenskab.
Kommentarer
<code>-taggen, for flere linjer - omslut dem i<pre>-tag, for mere end 10 linjer - brug en sandbox (plnkr, jsbin, codepen)