Dobra, zagrajmy trochę grę pamiętać:

z powyższego obrazka widzimy:
- Kiedy utworzyć funkcję jak
function Foo() {}
, JavaScript tworzy instancję Function
.
- Każda instancja
Function
(funkcja konstruktora) ma właściwość prototype
, która jest wskaźnikiem.
- Właściwość
prototype
wskazuje na obiekt prototypowy.
- Obiekt prototypowy ma właściwość
constructor
, która jest również wskaźnikiem.
- Właściwość obiektu prototypowego wskazuje na jego funkcję konstruktora.
- Kiedy tworzymy nową instancję
Foo
, taką jak new Foo()
, JavaScript tworzy nowy obiekt.
- Wewnętrzna właściwość
[[proto]]
wskazuje na prototyp konstruktora.
Teraz powstaje pytanie, dlaczego JavaScript nie dołącza do obiektu instancji obiektu zamiast prototypu. Rozważmy:
function defclass(prototype) {
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
var Square = defclass({
constructor: function (side) {
this.side = side;
},
area: function() {
return this.side * this.side;
}
});
var square = new Square(10);
alert(square.area()); // 100
Jak widać własnością constructor
jest po prostu inna metoda prototypu, jak area
w powyższym przykładzie. Cechą wyróżniającą właściwość constructor
jest jej inicjalizacja wystąpienia prototypu. W przeciwnym razie jest dokładnie taka sama, jak każda inna metoda prototypu.
Definiowanie właściwości constructor
na prototypie jest korzystne z następujących powodów:
- To logicznie poprawne. Na przykład rozważ
Object.prototype
. Właściwość constructor
z Object.prototype
wskazuje na Object
. Jeśli właściwość constructor
została zdefiniowana w instancji, wówczas Object.prototype.constructor
będzie undefined
, ponieważ Object.prototype
jest instancją null
.
- To nie jest traktowane inaczej niż inne prototypowe metody. To sprawia, że zadanie
new
jest łatwiejsze, ponieważ nie musi definiować właściwości dla każdej instancji.
- Każda instancja ma tę samą właściwość
constructor
. Dlatego jest wydajny.
Teraz, gdy mówimy o dziedziczeniu, mamy następujący scenariusz:

z powyższego obrazka widzimy:
- konstruktora potomnej
prototype
właściwość jest ustawiona na wystąpienie podstawowego konstruktora.
- W związku z tym wewnętrzna właściwość
[[proto]]
instancji konstruktora pochodnego wskazuje na to również.
- Tym samym właściwość
constructor
wyjściowej instancji konstruktora wskazuje teraz na konstruktor bazowy.
Co się tyczy operatora instanceof
, w przeciwieństwie do powszechnego przekonania, nie jest zależne od właściwości instancji danej constructor
. Jak widać z góry, doprowadziłoby to do błędnych wyników.
Operator instanceof
jest operatorem binarnym (ma dwa operandy). Działa na obiekcie instancji i funkcji konstruktora. Jak wytłumaczyć na Mozilla Developer Network, po prostu wykonuje następujące operacje:
function instanceOf(object, constructor) {
while (object != null) {
if (object == constructor.prototype) { //object is instanceof constructor
return true;
} else if (typeof object == 'xml') { //workaround for XML objects
return constructor.prototype == XML.prototype;
}
object = object.__proto__; //traverse the prototype chain
}
return false; //object is not instanceof constructor
}
Mówiąc prościej, jeśli Foo
dziedziczy Bar
, wówczas łańcuch prototypem instancji Foo
byłoby:
foo.__proto__ === Foo.prototype
foo.__proto__.__proto__ === Bar.prototype
foo.__proto__.__proto__.__proto__ === Object.prototype
foo.__proto__.__proto__.__proto__.__proto__ === null
Jak widać, każdy obiekt dziedziczy po konstruktorze Object
. Prototypowy łańcuch kończy się, gdy wewnętrzna właściwość [[proto]]
wskazuje na null
.
Funkcja instanceof
prostu przechodzi łańcuch prototyp obiektu przykład (pierwszy operand) i porównuje się z wewnętrzną [[proto]]
właściwość każdego przedmiotu, który ma właściwości prototype
funkcji konstruktor (drugiego argumentu). Jeśli pasują, zwraca true
; w przeciwnym razie, jeśli łańcuch prototypów się kończy, zwraca false
.
Każdy powód, dla którego potrzebujesz aktualizacji konstruktora? Uważam, że moje życie jest łatwiejsze, gdybym tylko udawał, że własność nie istnieje. – hugomg
Trudno jest zamknąć to jako duplikat - wszystkie inne questinos są tak szczegółowe ... – hugomg
'c.prototype' to' b() 'i' b.prototype' to 'a()', dlatego 'c.prototype' to' a() ' –