Domanda

Nel libro "JavaScript, la guida definitiva 5 edizione", la sezione 9.2 Prototipi e di Eredità, trovo le seguenti parole:

Nella sezione precedente, ho mostrato che l'operatore new crea un nuovo e vuoto oggetto e quindi richiama un costruttore la funzione di un metodo dell'oggetto.Questa non è la storia completa, tuttavia.Dopo aver creato il vuoto oggetto nuovo set di prototipo di quel oggetto.Il prototipo di un oggetto è il valore del prototipo di proprietà di la sua funzione di costruzione.Tutti funzioni di realizzare un prototipo di proprietà e che viene creata automaticamente inizializzato quando la funzione è definite. Il valore iniziale del proprietà prototype è un oggetto con un singola proprietà.Questa proprietà è nome del costruttore e rinvia per la funzione di costruzione, con la quale il prototipo è associato. (Si può ricordare la proprietà constructor dal Capitolo 7 ;questo è il motivo per cui ogni oggetto ha una proprietà constructor.) Qualsiasi proprietà si aggiunge a questo oggetto prototipo sembra essere proprietà degli oggetti inizializzato il costruttore.

Ora, se è vero, come potrebbe ereditarietà prototipale esiste?Voglio dire, diciamo che il prototipo oggetto di una funzione di costruzione ha una proprietà constructor inizialmente.Perché il prototipo di un oggetto è un oggetto, per determinare il suo costruttore, usiamo spesso prototype_object.constructor.Ma ora il prototype_object ha già un constructor struttura in sé, e che punti a la funzione di costruzione, con la quale il prototipo è associato.In questa situazione, come può eredità esiste?

È stato utile?

Soluzione

diciamo, cane è un mammifero.

function Mammal() {
  this.milk = true;
};

function Dog() { this.bark = true; } Dog.prototype = new Mammal;

Quindi, prototipo di punti cane a un oggetto di Mammifero . Questo oggetto mammifero ha un riferimento al suo costruttore in modo che quando Dog è nuovo, JavaScript vedere che Dog prototipo è un mammifero così il costruttore di mammifero è chiamato a produrre un oggetto Mammifero valida (un altro), allora ne fanno un oggetto di cane utilizzando il costruttore cane.

Da questo, il costruttore di Dog.prototype è un Mammal (un mammifero oggetto che ha campi aggiuntivi e funzioni aggiunte) MA costruttore Dog è Dog. Exist eredità perché l'un'istanza di cane ha un mammifero come un prototipo; quindi, Dog è un mammifero. Quando un metodo viene chiamato e JS non riesce a trovare da Dog.prototype, JS sguardo Mammal.prototype (che è un oggetto che ha campi aggiuntivi e funzioni aggiunte).

Spero che questo aiuti.

Altri suggerimenti

Il .constructor proprietà onestamente non importa molto, e ha molto poco a che fare con ereditando da altri oggetti in JavaScript.È solo una comoda maniglia per un costruttore di un oggetto.

Per esempio, se si dispone di un'istanza di qualcosa, e si desidera creare un altro esempio di che cosa, ma non hanno un diretto maniglia sul suo costruttore, si potrebbe fare qualcosa di simile a questo:

const myCar = new Racecar();
console.log(myCar.constructor); // [Function: Racecar]

const car2 = new myCar.constructor();
console.log(car2.constructor); // [Function: Racecar]

È importante capire che il .constructor la struttura e la classe di un oggetto non sono sinonimi.Come avrete già indovinato, la .constructor la struttura è dinamica, proprio come la maggior parte delle altre cose in JavaScript, quindi non dovrebbe essere usata per qualsiasi tipo di controllo.

E ' anche importante capire che il .constructor proprietà non vuol dire che qualcosa è una sottoclasse di qualcos'altro.In realtà, non vi è alcun modo affidabile per scoprire se qualcosa è una sottoclasse di qualcosa in JavaScript.Perché è un linguaggio dinamico, e perché ci sono così tanti modi per ereditare la proprietà da parte di altri oggetti (tra cui la copia di proprietà da parte di altri oggetti dopo l'istanza), type-safe sottoclassi non esiste in JavaScript come esistono in altre lingue.

Il modo migliore per sapere se qualcosa è compatibile con tipo di caratteristica-test di proprietà.In altre parole, anatra tipo.

Il instanceof operatore ignora il .constructor proprietà.Invece, si controlla se o non il costruttore .prototype esiste (con un controllo d'identità) nella catena dei prototipi dell'oggetto.

Manuale con le funzioni di costruzione, l'eredità può confondere il .constructor proprietà della connessione (il che rende consultare sbagliato costruttore).Si può risolvere il problema manualmente il cablaggio del collegamento.Per esempio, il modo canonico di farlo in ES5 è questo:

function Car () {}

console.log(Car.prototype.constructor); // Car

function Racecar () {}

Racecar.prototype = Object.create(Car.prototype);
// To preserve the same relationship we have with the Car
// constructor, we'll need to reassign the .prototype.constructor:
Racecar.prototype.constructor = Racecar;

var myCar = new Racecar();
console.log(myCar.constructor); // [Function: Racecar]

ES6 classi di farlo automaticamente per voi:

// ES6
class Car {}
class Racecar extends Car {}

const myCar = new Racecar();
console.log(myCar.constructor); // [Function: Racecar]

Detto questo, io non sono un grande fan di entrambi le funzioni di costruzione o ES6 classi, e io di solito scarsa utilità per l' .constructor proprietà.Perché?A causa di fabbrica le funzioni sono molto più flessibili, molto più potente, e non hanno le insidie legate a funzioni di costruzione e di ereditarietà di classe.Vedere "La fabbrica di Funzioni vs Costruttore Funzioni vs Classi".

Non si preoccupi per la proprietà constructor - è irrilevante. Salta quelle frasi e si potrebbe seguire meglio.

Se non siete ancora sicuri della vostra comprensione, google per __proto__ - il riferimento prototipo interno JS oggetti. E 'anche esposto a script su Firefox e Safari.

Un riferimento bene è https://developer.mozilla.org /en/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties/Inheriting_Properties

Se si ha un obj oggetto, è il prototipo è obj.prototype e costruttore di immobili riferibile al costruttore di obj è obj.prototype.constructor.

Per la obj.prototype oggetto la situazione è la stessa. proto = obj.prototype esempio di Let, quindi il riferimento al costruttore di proto sarebbe stata trovata in proto.prototype.constructor.

Questa è la stessa di obj.prototype.prototype.constructor, quindi non c'è alcun conflitto con obj.prototype.constructor.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top