2013-04-08 19 views
7

Proszę sprawdzić poniższy przykład:Telefoniczny klasa podstawowa funkcja - klasa dziedziczenie w JavaScript

MyBaseClass = function(a) { 
    this.a = a; 
}; 

$.extend(MyBaseClass.prototype, { 
    init: function() { 
     console.log('I am initializing the base class'); 
    } 
}); 

MyChildClass = $.extend(MyBaseClass, { 
    init: function() { 
     MyBaseClass.prototype.init(); 
     console.log('I am initializing the child class'); 
    } 
}); 

var = new MyChildClass(); 
var.init(); 

Тhis powinny wyjście zarówno „ja inicjalizacji klasy bazowej” i "Jestem inicjowanie klasę dziecka.

Potrzebuję móc odziedziczyć klasę MyBaseClass, ale wciąż móc wywołać jego metodę init() na początku nowej metody init().

Jak to zrobić?

+3

'$ .extend' nie robi co myślisz. –

+1

rodzajem rażącego problemu z tym kodem jest użycie 'var' na dole –

+3

Co to jest' $ .extend' mimo to? –

Odpowiedz

17

jQuery's extend nie buduje dziedziczenia, ale "Scal zawartość dwóch lub więcej obiektów razem w pierwszy obiekt".

Zastosowanie prototype based inheritance aby osiągnąć swoje dziedzictwo i jawnie wywołać "super" metodę:

MyBaseClass = function(a) { 
    this.a = a; 
}; 
MyBaseClass.prototype.init = function() { 
    console.log('I am initializing the base class'); 
}; 

MyChildClass = function(a) { 
    this.a = a; 
} 
MyChildClass.prototype = Object.create(MyBaseClass.prototype); // makes MyChildClass "inherit" of MyBaseClass 
MyChildClass.prototype.init = function() { 
    MyBaseClass.prototype.init.call(this); // calls super init function 
    console.log('I am initializing the child class'); 
}; 

var child= new MyChildClass(); 
child.init(); 

Output:

I am initializing the base class 
I am initializing the child class 
+0

Czy należy tu użyć 'Object.create'? –

+0

Ponieważ OP mówi o "klasach" i dziedziczeniu, osobiście uważam, że prototyp jest bardziej odpowiedni. –

+2

Być może Jan zamierzał użyć 'MyChildClass.prototype = Object.create (MyBaseClass.prototype);'. Byłoby to lepsze podejście do dziedziczenia IMHO. Wywoływanie nowej instancji rodzica * może * mieć wady. –

1

jsFiddle Demo

kilka rzeczy. extend po prostu dodaje właściwości, nie robi zbyt wiele. Musisz więc mieć funkcję dla swojej klasy, dziedziczyć po klasie bazowej, a następnie użyć rozszerzenia na prototypie tej klasy.

function MyChildClass(){}; 
MyChildClass.prototype = new MyBaseClass(); 
$.extend(MyChildClass.prototype, { 
init: function() { 
    MyBaseClass.prototype.init(); 
    console.log('I am initializing the child class'); 
} 
}); 

Oto kolejne podejście, które lubię używać do dziedziczenia - gdy specyfika metod będzie problemem - co jest przechowywanie klasę bazową w swoim majątku

function MyChildClass(){}; 
MyChildClass.prototype = new MyBaseClass(); 
MyChildClass.prototype.base = new MyBaseClass(); 
$.extend(MyChildClass.prototype, { 
init: function() { 
    this.base.init(); 
    console.log('I am initializing the child class'); 
} 
}); 
1

Another prototyp oparty wzór, aby osiągnąć ten cel:

MyBaseClass = function(a) { 
    this.a = a; 
}; 

MyBaseClass.prototype = { 
    init: function() { 
     console.log('I am initializing the base class'); 
    } 
}; 

MyChildClass = function() {}; 
MyChildClass.prototype = $.extend(new MyBaseClass(), { 
    init: function() { 
     this.super.init.call(this); 
     console.log('init child'); 
    }, 
    super: MyBaseClass.prototype, 
    constructor: MyChildClass 
}); 

var a = new MyChildClass(); 
a.init(); 

wyjściowa:

I am initializing the base class 
init child 

W tym miejscu odniesienie do klasy bazowej to this.super.

+0

Uczciwe pytanie: dlaczego określasz konstruktora? –

+0

@dystroy - faktycznie widziałem to w kodzie źródłowym jquery.Myślę, że dzieje się tak dlatego, że czasami konstruktor wskazuje czasami na niewłaściwą funkcję (nie jest w stanie zapamiętać dokładnego scenariusza, aby to zrobić w danym momencie). –

+0

@dystroy Aby móc używać 'instanceof'. 'instanceof MyChildClass' – dfsq

Powiązane problemy