Hur fungerar .call i JavaScript?


Jag har sett den här koden på MDN-sidan:

01  function Product(name, value){
02     this.name = name;
03     if(value >= 1000)
04        this.value = 999;
05     else
06        this.value = value;
07  }
08   
09  function Prod_dept(name, value, dept){
10     this.dept = dept;
11     Product.call(this, name, value);
12  }
13   
14  Prod_dept.prototype = new Product();
15   
16  // since 5 is less than 1000, value is set
17  cheese = new Prod_dept("feta", 5, "food");
18   
19  // since 5000 is above 1000, value will be 999
20  car = new Prod_dept("honda", 5000, "auto");

Det står att du kan använda call för att kedja konstruktörer. Jag har några frågor:

1) Varför kallas rad 14, varför skulle vi lägga till den till prototypen och varför skulle det innebära att Product kallas när vi skapar Prod_dept?

2) Vad betyder rad 11? Hur är detta relaterat till prototypen?

3) Vad är rad 20 menad att visa oss?

Svar #1

1) Att sätta en instans av Product som prototypobjekt för Prod_dept lägger till värdena och metoderna från den Product-instansen (och dess prototyp) till prototypkedjan för alla dina Prod_dept-instanser.

Det gör det också möjligt för instanceof att visa att ett objekt som skapats från Product_dept är en instans av båda konstruktörerna

var a = new Product();
var b = new Product_dept();

a instanceof Product       // true
a instanceof Product_dept  // false

b instanceof Product       // true
b instanceof Product_dept  // true

2) Eftersom this är det nya objektet som skapas av Prod_dept, låter .call dig sätta det objektet som this-värdet för Product-metoden, så att vad än Product-metoden gör med this kommer att göras på den nya Prod_dept-instansen (i detta fall körs koden för att lägga till värden till name och value-egenskaperna).

3) Det skapar bara en ny instans från Prod_dept-konstruktorn.

Överlag är detta ett mönster för att använda JavaScripts prototypbaserade arv-mekanism.

Svar #2

Koden visar helt enkelt prototypbaserat arv i JavaScript.

1) Vad koden säger på rad 14 är att du vill att din Prod_dept-funktion ska ärva egenskaperna och karaktärsdragen hos basklassen Product-funktionen.

Varje funktion i JavaScript har en prototype-egenskap och den innehåller ett objekt som du kan lägga till metoder och egenskaper på.

Prototype är en speciell egenskap som skapas så snart du definierar funktionen. Dess ursprungliga värde är ett tomt objekt {} men kan skrivas över för att låta dig definiera dina egna metoder eller ärva dem från en annan funktion.

2) Rad 10 tilldelar helt enkelt en egenskap till din Prod_dept-funktion, värdet som tillhandahålls av dept-argumentet som skickas genom konstruktorn.

3) Rad 14 tillåter dig att tillämpa de andra två argumenten "name, value" på din grundläggande Product-funktion men i sammanhanget av din Prod_dept-funktion. Ytterligare information om den metoden kan hittas här.