__proto__
Si può effettivamente accedere alla [[Prototype]]
proprietà interna di un oggetto con __proto__
. È possibile pensare a [[Prototype]]
come padre effettivo dell'oggetto corrente, nella gerarchia di ereditarietà.
prototype
Questa è una proprietà speciale, quando impostato su un oggetto funzione (costruttore), utilizzato per stabilire la catena di ereditarietà di istanze create dal costruttore. Ad esempio,
function Foo() {}
Foo.prototype = {a: 1};
Ora, quando si crea un nuovo oggetto di tipo Foo
, [[Prototype]]
proprietà interna dell'oggetto appena creato farà riferimento l'oggetto Foo.prototype
. È possibile confermare che in questo modo
console.assert((new Foo()).__proto__ === Foo.prototype);
Nel tuo caso,
myFunc.prototype = myObj;
si sta creando una proprietà prototype
sul oggetto funzione e questo sarà usato solo quando si creano nuovi oggetti con questa funzione (funzione costruttore). Potresti volerlo pensare come modello per i nuovi oggetti. Quindi, quando fai il myFunc.a
, il motore JS prova a trovare a
nel myFunc
e i suoi genitori nella catena del prototipo e non lo trova, ecco perché restituisce undefined
.
Ma, quando si fa
myFunc.__proto__ = myObj;
si sta impostando il genitore di myFunc
, nella catena di prototipi, per myObj
. Pertanto, quando esegui il comando myFunc.a
, il motore JS tenta prima di trovare a
nell'oggetto myFunc
e non è lì. Quindi, cerca di trovarlo nel suo genitore immediato, che è myObj
. Questo è il motivo per cui restituisce 1
in questo caso.
Nota: È possibile utilizzare la seguente funzione per capire la catena di prototipi meglio
function printPrototypeChain(object) {
while (object !== null) {
console.log(object);
object = Object.getPrototypeOf(object);
}
}
Ora, cerchiamo di stampa della catena di prototipi quando l'oggetto viene impostato come prototype
di proprietà della funzione oggetto.
function myFunc() {}
myFunc.prototype = {
a: 1,
b: 2
};
printPrototypeChain(myFunc);
L'uscita sarà
[Function: myFunc]
[Function: Empty]
{}
Nessuno di questi oggetti hanno a
definito, così undefined
viene restituito. Ma, in questo caso,
function myFunc() {}
myFunc.__proto__ = {
a: 1,
b: 2
};
printPrototypeChain(myFunc);
la catena di prototipi diventa come questo
[Function: myFunc]
{ a: 1, b: 2 }
{}
e a
si trova in padre immediato myFunc
s'. Quindi, viene restituito il valore corrispondente 1
.
Nota: Non utilizzare __proto__
nel codice vero e proprio, in quanto viene mantenuto nelle ultime versioni della specifica JavaScript solo per la compatibilità a ritroso. Per saperne di più su di esso here. Utilizzare invece Object.getPrototypeOf
e Object.setPrototypeOf
.
http://es5.github.io/ non sa nulla di '__proto__'. Il che significa che non fa parte dello standard e non dovresti mai usarlo. – zerkms
No, il prototipo di un oggetto (quello con cui eredita da) è ** non ** il '.prototype'. Hai letto tutte le risposte a http://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript? Cosa non hai capito in modo specifico (siamo felici di migliorarli)? – Bergi
allora che cos'è .prototype usato per ?? – Flake