Ho qualche problema a decifrare l'ereditarietà prototipica in JavaScript e ho pensato di pubblicarlo qui. Considerate questo semplice esempio:Qual è la necessità di call() nell'ereditarietà prototipica
function Employee() {
this.name = "Rob";
this.dept = "R&D";
}
function Manager() {
//Employee.call(this);
this.reports = ["Report 1", "Report 2", "Report 3"];
}
Manager.prototype = Object.create(Employee.prototype);
Employee.prototype.type = "human";
m = new Manager();
console.log(m.name); //undefined
console.log(m.type); //human
Quello che non riesco a capire è l'utilità della linea Employee.call(this)
. Dal momento che stiamo impostando Employee.protoype come prototipo di Manager, qual è la necessità (come la vedo io) di forzare esplicitamente la creazione di variabili in Employee attraverso call()
? In precedenza ho pensato che potesse essere dovuto al fatto che non esiste alcun oggetto di Employee
e che l'ereditarietà JS non può funzionare senza oggetti, quindi call()
viene qui utilizzato per "completare la creazione dell'oggetto". Tuttavia, la proprietà type
viene riflessa in Manager senza la necessità di call()
, il che dimostra che non è necessario un oggetto rigido per eseguire l'ereditarietà (ciò che intendo è, solo la definizione della funzione di costruzione simile alla classe farà).
Spero di non averlo reso troppo complicato. In breve: perché è necessario call()
qui e perché la proprietà type
funziona senza call()
(se call()
è così importante, cioè).
"Lo scopo di Employee.call (this) è di aggiungere gli attributi di nome e reparto alle istanze di Manager." Quindi cos'è 'Manager.prototype = Object.create (Employee.prototype);' doing? Perché non porta ad ereditare quei valori? "L'uso di call() è più per convenzione e consente di modificare il chiamante (questo) sul posto." So cosa, ma perché è necessario? In eredità, stiamo parlando di classi e progetti (spero) non di oggetti.Forse quello che sto chiedendo è più sulle linee della filosofia del design del linguaggio, ma alcune risposte approfondite sarebbero più utili. – dotslash
Object.create() copia solo sui prototipi. Le proprietà name e dept non sono nel prototipo ma nel costruttore, quindi non vengono copiate automaticamente. Se andassi Manager.prototype = Object.create (Employee), anche 'name' e 'dept' verrebbero copiati, ma l'uso della chiamata per fare ciò è più diffuso. – Shilly
@dotslash in effetti, non ci sono classi in JavaScript (anche se EcmaScript 6 potrebbe farcelo credere). Esistono solo oggetti che delegano ad altri oggetti. Lavorare con l'operatore 'new' non fa che falsificare un'eredità pseudo-classica. Ma non è così che javascript funziona all'interno. Il seguente post di Eric Elliott potrebbe aiutare a chiarire le cose: https://medium.com/javascript-scene/common-misconceptions-about-inheritance-in-javascript-d5d9bab29b0a – nils