为什么方法的`this`在调用对象方法的引用时会改变?

时间:2011-10-05 06:46:55

标签: javascript

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();警报undefined对我来说并不清楚。如果我看到它我相信它就像它上面的线一样。有些人可以解释一下细节

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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的值是多少。通常是调用函数的object之前的dot。例如:

person1.sayGender()此处this = person1

object1.object2.foo()此处this = object2

genderTeller()此处this = window,因为您没有从任何对象调用它。

显然,您可以使用this.call函数设置.apply的值,但通常在为代码构建心理模型时遵循此规则。

答案 2 :(得分:3)

您正在调用没有其对象上下文的函数,因此this将是全局对象window,因此该函数会警告window.gender的值{{1} }}