2016-04-19 14 views
6

Pytam jak zaimplementować funkcję wirtualną w javascript, takich jak C#, powiedzmywirtualnej funkcji w JavaScript

  • Mam klasy bazowej
  • Mam też klasa pochodna o nazwie B
  • Klasa A ma funkcję o nazwie virtualFunction, która ma być funkcją wirtualną, jak w C#, może być nadpisana w pochodnej klasie B
  • Funkcja zostanie wywołana do wykonania wewnątrz konstruktora klasy bazowej, A. Jeśli funkcja zostanie nadpisana w B, B zostanie wywołana o termostat A zostanie wywołany:

W tym przykładzie poniżej chcę uzyskać alert "B", a nie "A".

function A() { 
 
    this.virtualFunction(); 
 
} 
 

 
A.prototype.virtualFunction = function() { 
 
    alert('A'); 
 
}; 
 

 
//------------------------------------- 
 

 
function B() {} 
 

 
B.prototype = new A(); 
 
B.prototype.virtualFunction = function() { 
 
    alert('B'); 
 
}; 
 

 
var b = new B();

Gdybyśmy wywołać funkcję po instancja, tak, to jest w porządku, ale muszę "wewnątrz konstruktora"

var b = new B(); 
 
b.virtualFunction();

+2

W pierwszym przypadku trzeba 'alert („A”)' w obu dominujących i podrzędnych funkcji – MysterX

+3

Nawet w C#, konstruktor klasy base nie ma dostępu do funkcji w klasa pochodna. Podczas gdy podstawowy konstruktor działa, obiekt nie jest jeszcze instancją klasy pochodnej, więc przesłonięcia klasy pochodnej nie zostały jeszcze skonfigurowane. Generalnie nie byłby bezpieczny wywoływanie metod w klasie pochodnej przed uruchomieniem konstruktora pochodnego. – Wyzard

+0

[Nie używaj nowych do tworzenia prototypowych obiektów!] (Https://stackoverflow.com/questions/12592913/what-is-the-reason-to-use-the-new-keyword-tutaj) Zamiast tego umieść super call w 'B', a otrzymasz oczekiwane rezultaty. – Bergi

Odpowiedz

4

Pierwszą rzeczą, jaką należy sobie uświadomić, jest to, że JavaScript nie używa tej samej semantyki co C#. Próba, aby to zrobić, spowoduje ból serca; dużo lepiej nauczysz się, jak się robi w JS. W rzeczywistości, większość ludzi nie próbuje zrobić wiele rzeczy typu dziedziczenia w JS, ale zamiast tego faworyzuje kompozycję (która jest właściwie najlepszą praktyką we wszystkich językach OO, które znam).

To powiedziawszy, możesz wprowadzić kilka ulepszeń do swojego kodu.

function A() { 
 
    this.virtualFunction(); 
 
} 
 

 
A.prototype.virtualFunction = function() { 
 
    alert('A'); 
 
}; 
 

 
//------------------------------------- 
 

 
function B() { 
 
    A.call(this); 
 
} 
 

 
B.prototype = Object.create(A.prototype); 
 
B.prototype.constructor = B; 
 
B.prototype.virtualFunction = function() { 
 
    alert('B'); 
 
}; 
 

 
var b = new B();

+0

dziękuję Paul, właśnie tego chcę. Jestem tylko ciekawy, dlaczego musimy mieć B.prototype.constructor = B; Nadal będzie dobrze, jeśli usunę ten wiersz kodu. Kiedy jest to obowiązkowe? – khoailang

+0

Jeśli nie, konstruktorem dla B będzie A, ponieważ kod ten ustawia cały prototyp B na klon prototypu A. W przeciwieństwie do C# funkcja "constructor" jest po prostu inną metodą na prototypie. – Paul

+0

Zostałem oznaczony jako odpowiedź, ponieważ to jest to, czego potrzebuję, dziękuję. Czy możesz jednak wyjaśnić, dlaczego usunąłem B.prototype.constructor = B, który nadal jest w porządku, działa dokładnie tak samo, "konstruktor" B nadal jest trafiony? Czy możesz mi pomóc na przykład, że brak B.prototype.constructor = B powoduje błąd? – khoailang

Powiązane problemy