2010-10-18 8 views
9

Robię OO javascript po raz pierwszy. Czytałem o dziedziczeniu i prototypie i myślałem, że je złamałem. Aż odkryłem ten mały przykład.Dziedziczenie w javascript, zmienne w "nadrzędnym"

function TestObject(data) 
{ 
    this.test_array = []; 
    this.clone_array = []; 

    this.dosomestuff = function() 
    { 
     for(var i=0; i<this.test_array.length; i++) 
     { 
      this.clone_array[i]=this.test_array[i]; 
     } 
    } 

    this.__construct = function(data) 
    { 
     console.log("Testing Object Values" ,this.clone_array); 
     this.test_array = data; 
    }; 
} 

TestObject2.prototype = new TestObject(); 

function TestObject2(data) 
{ 
    this.__construct(data); 
    this.dothings = function() 
    { 
     this.dosomestuff(); 
    } 
} 

Gdybym wykonaj następujące czynności:

var foo = new TestObject2([1,2,3,4]); 
foo.dothings(); 
var bar = new TestObject2([4,5,6]); 
bar.dothings(); 

spodziewałbym konsola do pokazania:

Testing Object Values, [] 
Testing Object Values, [] 

Jednak to pokazuje:

Testing Object Values, [] 
Testing Object Values, [1,2,3,4] 

Problemem jest oczywiście to połączenie:

TestObject2.prototype = new TestObject(); 

W jaki sposób uzyskać zmienne nadrzędne w TestObject, aby "zresetować" inne niż ręczne resetowanie ich w metodzie __construct?

Czy istnieje inny sposób na testObject2 dziedziczenia wszystkich wartości/metod z TestObject i dla "nowych" zachowywać się tak, jak bym się spodziewał w trybie PHP OO? (Jestem pewien, że sposób, w jaki robi to JS, jest naprawdę naprawdę dziwny, jak gdyby mój mózg służył mi poprawnie z University Java działa jak PHP w tym zakresie)

+0

Demo tutaj: http://jsbin.com/olino3 – johnwards

Odpowiedz

10

Zasadniczo

TestObject2.prototype = new TestObject(); 

umieszcza pojedynczej instancji TestObject w łańcuchu prototypu TestObject2. W związku z tym wszelkie instancje obiektu TestObject2 zmodyfikują tę samą właściwość potomną pojedynczej instancji w obiekcie TestObject. Jeśli umieścisz kolejną konsolę.log w koncerze TestObject, zauważysz, że jest on wywoływany tylko raz!

Więcej szczegółowych informacji na temat problemu można znaleźć pod adresem here.

Musisz wywołać konstruktora textobject od wewnątrz konstruktora TextObject2 tak:

function TestObject2(data) 
{ 
    TestObject.call(this, data); 
    this.__construct(data); 
    this.dothings = function() 
    { 
     this.dosomestuff(); 
    } 
} 

Wywołując funkcję konstruktora TestObject i wykonanie go w zakresie (jest) nowy obiekt TestObject2, tworzy wszystkie elementy obiektu TestObject w obiekcie TestObject2.

+0

Doskonały, dokładnie to, czego szukałem. Masz również głosowanie na górze! – johnwards

+0

Doh, zapomniałem o wywołaniu do odziedziczonego konstruktora. Dobre oko. – JoshNaro

0

Czy próbowałeś już zdefiniować this.clone_array = []; zamiast TestObject2?

function TestObject2(data) 
{ 
    this.clone_array = []; 
    this.__construct(data); 
    this.dothings = function() 
    { 
     this.dosomestuff(); 
    } 
} 
+0

Mam 30 zmiennych w moim rodzicu. Rozszerzam rodzica w 3 różnych klasach. Musiałbym skopiować i wkleić reset do tych 30 klas. Paskudny. Byłoby mi lepiej, gdyby je zresetowałem. – johnwards

0

myślę

TestObject2.prototype = new TestObject(); 

jest nadrzędne konstruktora TestObject2.

Spróbuj

function TestObject2(data) 
{ 
    TestObject.call(this, data); 
    this.__construct(data); 
    this.dothings = function() 
    { 
     this.dosomestuff(); 
    } 
} 


TestObject2.prototype = new TestObject(); 
TestObject2.prototype.constructor = TestObject2; 
+0

Nie ma różnicy. Zobacz: http://jsbin.com/olino3/3 – johnwards

Powiązane problemy