Stavo leggendo su come la proprietà del prototipo Javascript funziona con l'ereditarietà e poi ho iniziato a consultare il codice Angular.js e ho trovato alcune domande.Perché assegnare qualcosa a Something.prototype.constructor?
Prima di tutto, ho letto che la proprietà prototype punta a un oggetto che ha una proprietà "costruttore" che punta alla funzione originale utilizzata per creare l'oggetto. Così, per esempio:
// This is the constructor
function Shape() {
this.position = 1;
}
// The constructor points back to the original function we defined
Shape.protoype.constructor == Shape;
Il prototipo contiene anche tutti gli altri metodi o proprietà che sono state definite su di essa da noi o dal linguaggio Javascript per sé, e questi sono condivisi da tutte le istanze dell'oggetto. Se vuoi che un oggetto chiamato Square erediti da Shape devi impostare il prototipo di Square uguale a una nuova istanza di Shape perché la proprietà interna [[prototype]] di Square.prototype viene impostata sul valore dell'oggetto pubblico della proprietà Shape.prototype .
function Square() {}
Square.prototype = new Shape();
var square = new Square();
square.position; // This will output 1
Tutto questo ha senso per me.
Tuttavia, il codice Angular.js di cui ho una domanda sembra essere correlato a tutto ciò ma fa qualcosa che non capisco. Non sembra che abbia a che fare con l'ereditarietà, quindi posso capire perché ci sarebbero delle differenze, ma sono solo curioso di sapere perché l'hanno scritto come hanno fatto.
All'interno di Angular.js, vi è un oggetto HashMap e un oggetto Lexer, ma sono definiti in modo diverso ma sembrano essere istanziati e utilizzati nello stesso modo. Il costruttore Lexer viene prima definito e quindi imposta il prototipo su un oggetto letterale contenente metodi che devono essere condivisi da tutte le istanze del Lexer. Tutto ciò ha senso. Quello che non capisco è il motivo per cui specificano la proprietà "costruttore" e la impostano solo su "Lexer" quando non lo sono per HashMap di seguito.
var Lexer = function(options) {
this.options = options;
};
// Notice they specify Lexer as the constructor even though they don't for HashMap below
Lexer.prototype = {
constructor: Lexer,
lex: function(text) { ... },
is: function(ch, chars) { ... },
peek: function(i) { ... },
isNumber: function(ch) { ... },
isWhitespace: function(ch) { ... },
isIdent: function(ch) { ... },
isExpOperator: function(ch) { ... },
throwError: function(error, start, end) { ... },
readNumber: function() { ... },
readIdent: function() { ... },
readString: function(quote) { ... }
};
Poi, se si guarda il codice HashMap, fanno la stessa cosa, tranne che non specificano la proprietà constructor. Perchè è questo? Sembra funzionare esattamente allo stesso modo, e ho provato che il costruttore viene ancora chiamato.
// The HashMap Constructor
function HashMap(array, isolatedUid) {
if (isolatedUid) {
var uid = 0;
this.nextUid = function() {
return ++uid;
};
}
forEach(array, this.put, this);
}
HashMap.prototype = {
put: function(key, value) { ... },
get: function(key) { ... },
remove: function(key) { ... }
};
Così è la proprietà constructor facoltativa quando non v'è alcuna eredità, così forse una persona ha scritto il Lexer e un altro la HashMap e uno ha deciso di indicare il costruttore?
vedere anche [Definizione di un prototipo di Javascript] (http://stackoverflow.com/q/17474390/1048572) – Bergi
@Bergi Grazie, questo aiuta. – Triad