2011-10-05 9 views
7
function Person(gender) { 
    this.gender = gender; 
} 

Person.prototype.sayGender = function() 
{ 
    alert(this.gender); 
}; 

var person1 = new Person('Male'); 
var genderTeller = person1.sayGender; 

person1.sayGender(); // alerts 'Male' 
genderTeller(); // alerts undefined 
 

Dlaczego genderTeller(); alerty nieokreślone nie są dla mnie jasne. jeśli to widzę, to uważam, że jest tak samo jak linia powyżej. Można niektóre proszę wyjaśnić szczegółyDlaczego metoda "this" zmienia się podczas wywoływania odwołania do metody obiektu?

Odpowiedz

14

Po przypisaniu zmiennej tak ...

var genderTeller = person1.sayGender; 

... tracisz kontekst obiektu person1, a funkcja jest this punkty do globalnego obiektu (window w przeglądarce) zamiast utworzonego obiektu person1.

Otrzymasz undefined ponieważ nieruchomość gender nie istnieje na window i odniesienie do niezdefiniowanej właściwości dla obiektu zwraca undefined w JavaScript.

można ustalić, że w nowoczesnych przeglądarkach z bind() ...

var genderTeller = person1.sayGender.bind(person1); 

... lub jQuery ma metodę zwaną też proxy().

var genderTeller = $.proxy(person1.sayGender, person1); 
+0

Jak "tracimy kontekst osoby 1 obiektu" jest nieco mylące. –

+0

@sushilbharwani: Ponieważ nie nazywasz tego od razu, po prostu przypisujesz odwołanie do funkcji w zmiennej. Tak działa JavaScript. – alex

3

Jesteś wywołanie funkcji bez kontekstu jego przedmiotu, więc this będzie globalny obiekt window, więc funkcja alarmuje wartość window.gender, który jest undefined.

5

Tak działa zakres JavaScript. Myślę, że poniższy przykład da ci dobry wgląd.

this.gender = 'Female'; 

function Person(gender) { 
    this.gender = gender; 
} 

Person.prototype.sayGender = function() 
{ 
    alert(this.gender); 
}; 

var person1 = new Person('Male'); 
var genderTeller = person1.sayGender; 

person1.sayGender(); // alerts 'Male' 
genderTeller(); // alerts 'Female' 

Istnieje prosty sposób dowiedzieć się, co jest wartością this w funkcji dzwonisz. Zwykle jest to object przed dot, w którym wywołałeś funkcję. Na przykład:

person1.sayGender() tutaj this = person1

object1.object2.foo() tutaj this = object2

genderTeller() tutaj this = window, ponieważ nie jesteś wywołanie go z dowolnego obiektu.

Oczywiście można ustawić wartość this z funkcją .call lub .apply, ale zwykle postępuję zgodnie z tą zasadą, gdy buduję model mentalny dla mojego kodu.

Powiązane problemy