2014-11-19 29 views
10

Wiem, że to działa, ale nie wiem dlaczego i jak. Jakie są mechanizmy?Wywołanie Javascript Konstruktor nadrzędny u dziecka (prototypowe dziedziczenie) - jak to działa?

// Parent constructor 
function Parent(name){ 
    this.name = name || "The name property is empty"; 
} 

// Child constructor 
function Child(name){ 
    this.name = name; 
} 

// Originaly, the Child "inherit" everything from the Parent, also the name property, but in this case 
// I shadowing that with the name property in the Child constructor. 
Child.prototype = new Parent(); 

// I want to this: if I dont set a name, please inherit "The name property is empty" from the 
// Parent constructor. But I know, it doesn't work because I shadow it in the Child. 
var child1 = new Child("Laura"); 
var child2 = new Child(); 

//And the result is undefined (of course) 
console.log(child1.name, child2.name); //"Laura", undefined 

wiem, co muszę, call() lub metoda apply(). Wywołanie "super klasy" (konstruktor Parent) z Child i przekazanie obiektu this i argumentu name. Działa:

function Parent(name){ 
    this.name = name || "The name property is empty"; 
} 

function Child(name){ 
    // Call the "super class" but WHAT AM I DO? How does it work? I don't understand the process, I lost the line. 
    Parent.call(this, name); 
} 

Child.prototype = new Parent(); 

var child1 = new Child("Laura"); 
var child2 = new Child(); 

console.log(child1.name, child2.name); // "Laura", "The name property is empty" 

Działa doskonale, ale nie rozumiem, co się dzieje. Zgubiłem w moim umyśle this i nie mogę śledzić procesu metody call(). Czy to kopiuje korpus konstruktora z Parent do Child lub co? A gdzie jest obiekt this? Dlaczego to działa?

Proszę pomóż i opisz proces, nie rozumiem.

+0

patrz: http: //stackoverflow.com/questions/20830449/object-create-changes-prototype-constructor-to-parent-constructor-but-upon-chil –

+0

pokrewnych https: // stackoverflow. com/a/29543030/632951 – Pacerier

+0

Umysł akceptujący odpowiedź? – plalx

Odpowiedz

21

Przede wszystkim przestań robić Child.prototype = new Parent(); dla dziedziczenia, chyba że twoja przeglądarka nie obsługuje żadnej innej alternatywy. Jest to bardzo zły styl i może powodować niepożądane efekty uboczne, ponieważ w rzeczywistości uruchamia logikę konstruktora.

Możesz teraz używać Object.create we wszystkich nowoczesnych przeglądarkach.

Child.prototype = Object.create(Parent.prototype); 

Należy pamiętać, że po tym należy również ustalić właściwość Child.prototypeconstructor tak, że prawidłowo wskazuje Child zamiast Parent.

Dalej, jak działa call? Dobrze call pozwala określić, który obiekt będzie się odnosił przez słowo kluczowe this, gdy funkcja zostanie wykonana.

function Child(name){ 
    //When calling new Child(...), 'this' references the newly created 'Child' instance 

    //We then apply the 'Parent' constructor logic to 'this', by calling the 'Parent' function 
    //using 'call', which allow us to specify the object that 'this' should reference 
    //during the function execution. 
    Parent.call(this, name); 
} 
+0

Ta technika nazywa się "kradzież konstruktorów" – dgtc

+1

Aby zademonstrować pełną mechanikę tego/konstruktora/wywołania, że ​​OP był ciekawy dziedziczenia prototypowego w/r/t, powinienem dodać "Child.prototype.constructor = Child ; " po linii "Child.prototype = Object.create (Parent.prototype)". Dopóki tego nie zrobisz, Child.prototype.constructor będzie równe Parent.prototype.constructor, co doprowadzi do pewnych niezamierzonych konsekwencji - szczególnie. jeśli zaczniesz dodawać argumenty i/lub funkcję inicjalizacji, która jest specyficzna dla konstruktora Child. Scenariusz ten nie został wyraźnie zgłoszony przez OP, ale warto to podkreślić. – herringtown

+1

Byłem tego świadomy i zazwyczaj naprawiam członka konstruktora, ale uważałem, że nie mieści się w zakresie odpowiedzi. Warto jednak wspomnieć o tym. – plalx