2011-10-05 83 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 
 

为什么genderTeller();未定义的警报不清楚。如果我看到它,我相信它和上面的线一样。可以请一些解释细节调用对象方法的引用时,为什么方法的this会改变?

回答

14

当你分配这样一个变量...

var genderTeller = person1.sayGender; 

...你失去了person1对象的背景,而该函数的this指向全局对象(window在浏览器中),而不是实例化的person1对象。

你得到undefined因为gender属性不上window存在,在对象上引用一个未定义的属性在JavaScript中返回undefined

您可以修复,在现代浏览器与bind() ......

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

...或jQuery有一个叫太方法proxy()

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

我们如何“失去person1对象的上下文”有点混乱。 –

+0

@sushilbharwani:因为你不会马上叫它,你只是在一个变量中分配一个对函数的引用。这就是JavaScript的工作原理。 – alex

3

要调用没有它的对象的上下文功能,使this将是全局对象window,因此函数提醒的window.gender的价值,这是undefined

5

这就是JavaScript范围的工作原理。我想下面的例子会给你一个很好的见解。

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' 

没有搞清楚什么是this在你调用一个函数值的简单方法。它通常是之前dot您调用该功能。例如:

person1.sayGender()这里this = person1

object1.object2.foo()这里this = object2

genderTeller()这里this = window,因为你不是从任何对象调用它。

很明显,你可以设置this值与.call.apply功能,但通常我遵循这个规则,当我建立我的代码的心理模型。

相关问题