2016-05-06 16 views
6

próbuję przesłonić metodę i skrypt jest:Javascript nie wywołać metodę prototypową

function wrapper(target) { 
    target.doABC = function() { 
     alert('in wrapper'); 
    }; 
    return target; 
} 

function Model() { 
    wrapper(this); 
} 

Model.prototype.doABC = function() { 
    alert('in Model'); 
}; 

var a = new Model(); 
a.doABC(); 

Rezultatem jest „w opakowaniu jednostkowym”. Nie wiem dlaczego?

+0

'Model' jest' obiektem', a 'obiekt' nie może mieć dwóch kluczy o tej samej nazwie! – Rayon

+0

@Rayon: 'shadow', a nie' override', aby użyć lepszej terminologii. OP nie przypisuje właściwości "Modelowi" dwukrotnie, przypisuje mu "Model" i prototyp. –

+0

@JeremyJStarcher, True .. Termin "przesłanianie" źle zinterpretuje rzeczy .. – Rayon

Odpowiedz

5

Każdy obiekt JavaScript ma własnych właściwości i dziedziczonych. Własne są zdefiniowane bezpośrednio w instancji, a dziedziczone są pobierane z obiektu prototype.
Podczas korzystania z obiektu o właściwościach dostępu , JavaScript najpierw wyszukuje w obiekcie własna lista obiektów . Jeśli właściwość nie zostanie znaleziona, wyszukuje w prototypowym łańcuchu obiektu .

W tym przykładzie metoda wrapper() definiuje na instancji obiektu własną właściwość doABC, która jest funkcją informującą o 'in wrapper'. Nawet jeśli obiekt ma prototyp z tą samą właściwością, doAbc, który alarmuje 'in Model', JavaScript i tak będzie używał własnej właściwości.

function wrapper(target) { 
    // Define an own property "doABC" 
    target.doABC = function() { 
     alert('in wrapper'); 
    }; 
    return target; 
} 

function Model() { 
    wrapper(this); 
} 

// Define an inherited property "doABC" 
Model.prototype.doABC = function() { 
    alert('in Model'); 
}; 

var a = new Model(); 

//Use the own property "doABC". The inherited "doABC" is ignored. 
a.doABC(); 

Jako dodatek, własność własną można usunąć za pomocą operatora delete. Po usunięciu obiekt użyje odziedziczonej właściwości.

// delete the own property "doABC" 
delete a['doABC']; 

// the inherited "doABC" will be used. Alerts "in Model" 
a.doABC(); 

Sprawdź pełna working demo.

+0

Dzięki za odpowiedź! – user3468795

+0

Próbowałem debugować ten skrypt. Przed uruchomieniem instrukcji target.doABC, obiekt a ma już metodę doABC() pochodzącą z prototypu.Po uruchomieniu target.doABC ta funkcja jest aktualizowana. – user3468795

+0

@ user3468795 Tak, dzieje się tak w konstruktorze. Moja odpowiedź brzmi: pytanie "Wynik jest" w opakowaniu ". Nie wiem dlaczego? ". –

1

Pozwól mi zobaczyć, czy mogę wyjaśnić:

Masz dwie oddzielne wersje doABC tutaj.

Twój target.doABC tworzy specyficzną funkcję do że otworzonym Model a każdy Model dostać swój własny doABC.

Ponieważ Model ma doABC, silnik JavaScript nie musi szukać "w górę łańcucha" dla czegoś innego, dlatego nigdy nie będzie szukał wersji Model.prototype.doABC.

Widać to dodając te wiersze:

Model.prototype.doXYZ = function() { 
    alert('in Model'); 
}; 

i nazywając

a.doXYZ(); 

Od a nie posiada własnego doXYZ wtedy i tylko wtedy, będzie to wyglądać w górę łańcucha i zobacz metodę w prototypie.

Powiązane problemy