2013-07-18 10 views
5

Wygląda na to, że w końcu rozumiem dziedziczenie JavaScriptu i jak powinno to być zrobione poprawnie. Tu jest mój kodu:Dziedziczenie JavaScriptu i prototypów

function Human(eyes) { 
    this.eyes = eyes ? "Not blind" : "Blind"; 
} 
Human.prototype.canSee = function() { 
    return this.eyes; 
}; 
function Male(name, eyes) { 
    Human.call(this, eyes); 
    this.name = name; 
} 
Male.prototype = Object.create(Human.prototype); 
var Sethen = new Male("Sethen", true); 
console.log(Sethen.canSee()); //logs "Not blind" 

Z tego co rozumiem, używając Object.create stworzyć swój obiekt prototypowy dla dziedziczenia jest znacznie lepsza niż przy użyciu słowa kluczowego new. Rodzi to parę pytań w mojej głowie.

  1. Czy w łańcuchu prototypów byłby Male.prototype = Object.create(Human.prototype)Male.prototype --> Human.prototype --> Object.prototype --> null?
  2. W konstruktorze Male, w którym używam Human.call(this, eyes); do wywoływania super klasy, muszę ponownie przekazać oczy w konstruktorze Male, aby przekazać go do konstruktora Human. To wydaje się jak ból, czy jest łatwiejszy sposób na zrobienie tego?
  3. Dlaczego czasami widzę kod taki jak Male.prototype = new Human(); ... To wydaje się być niepoprawne. Co się właściwie dzieje, kiedy to robimy?
+1

Czy widziałeś ten http://stackoverflow.com/questions/13040684/javascript-inheritance-object-create-vs-new i ten http://stackoverflow.com/ pytania/4166616/understanding-the-difference-between-object-create-and-new-somefunction-in-j ??? – rafaelcastrocouto

+0

Nie, nie mam. Ale popatrzę. – Sethen

Odpowiedz

3

Aby odpowiedzieć na Twoje pytania:

  1. Zgadza się. Po ustawieniu Male.prototype = Object.create(Human.prototype) ustawiasz łańcuch prototypów jako Male.prototype --> Human.prototype --> Object.prototype --> null. Następnie po utworzeniu var Sethen = new Male instancja (Sethen) dziedziczy z tego łańcucha prototypów.
  2. Nie, trzeba ręcznie przekazać parametry do funkcji konstruktora podstawowego. Jeśli chcesz, możesz ustawić this.eyes = eyes ? "Not blind" : "Blind" w samej funkcji Male, ale będzie to po prostu powielanie kodu. To, co robisz, jest poprawne.
  3. To był stary sposób robienia rzeczy (zanim standaryzowano Object.create). Polecam, żebyś go nie używał. W większości przypadków jest taka sama jak nowa metoda. Jednak za pomocą tej metody otrzymujesz również niechciane właściwości, takie jak eyes na Male.prototype.

Kiedy robimy Male.prototype = new Human tworzymy nową instancję Human i przypisać ją do Male.prototype. Stąd prototypowy łańcuch to Male.prototype --> Human.prototype --> Object.prototype --> null. Jednak otrzymujemy również nieruchomość Male.prototype.eyes, której nie wymagamy. To powinno należeć tylko do instancji Male.

Polecam przeczytać mój blog. To naprawdę dobry podkład na dziedziczenie prototypowe: Aadit M Shah | Why Prototypal Inheritance Matters

+0

Dzięki człowieku! To wyjaśniło mi rzeczy. Zakładałem, że otrzymujemy również pewne niechciane właściwości, takie jak "oczy", ale nie byłem pewien. – Sethen

+0

Zanim użyto funkcji Object.create pomocnika: http://stackoverflow.com/questions/16063394/prototypical-inethitance-writing-up/16063711#16063711 (nadal są, jeśli chcesz wspierać IE 8) W tych funkcjach pomocniczych konstruktor można ustawić na odpowiednią funkcję również po ustawieniu dziedziczenia. Nadal musisz to zrobić, jeśli planujesz użyć właściwości 'constructor'. – HMR

+1

@HMR Ah. Cóż, jedyną funkcją pomocniczą, której obecnie używam, jest ["augment"] (https://github.com/javascript/augment). Używa 'Object.create', ale możesz go zaimplementować bez użycia' Object.create'. –