Why does a method's `this` change when calling a reference to an object's method?
function Person(gender) {
this.ge开发者_高级运维nder = gender;
}
Person.prototype.sayGender = function()
{
alert(this.gender);
};
var person1 = new Person('Male');
var genderTeller = person1.sayGender;
person1.sayGender(); // alerts 'Male'
genderTeller(); // alerts undefined
Why does genderTeller(); alerts undefined is not clear to me. if I see it I believe it's just same as line above it. Can some please explain the details
When you assign a variable like this...
var genderTeller = person1.sayGender;
...you lose the context of the person1
object, and the function's this
points to the global object (window
in a browser), instead of the instantiated person1
object.
You get undefined
because the gender
property does not exist on window
, and referencing an undefined property on an object returns undefined
in JavaScript.
You can fix that in modern browsers with bind()
...
var genderTeller = person1.sayGender.bind(person1);
...or jQuery has a method too called proxy()
.
var genderTeller = $.proxy(person1.sayGender, person1);
This is how JavaScript scope works. I think the following example will give you a good insight.
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'
There is a simple way of figuring out what is the value of this
in a function you are calling. It is usually the object
before the the dot
where you invoked the function. For example:
person1.sayGender()
here this
= person1
object1.object2.foo()
here this
= object2
genderTeller()
here this
= window
, because you are not calling it from any object.
Obviously you can set the value of this
with .call
or .apply
function but usually I follow this rule when I build a mental model for my code.
You are calling the function without the context of its object, so this
will be the global object window
, so the function alerts the value of window.gender
, which is undefined
.
精彩评论