I found this example code:
function personFullName() {
return this.first + ' ' + this.last;
}
function Person(first, last) {
this.first = first;
this.last = last;
this.fullName = personFullName;
}
var dude = new Person("Michael", "Jackson");
alert(dude.fullName());
Which alerts "Michael Jackson". I changed it to call personFullName
from the constructor instead of assigning the function object:
function personFullName() {
return this.first + ' ' + this.last;
}
function Person(first, last) {
this.first = first;
this.last = last;
this.fullName = personFullName();
}
var dude = new Person("Michael", "Jackson");
alert(dude.fullName);
I would expect the "fullName" property to now be a string instead of a function. But now it alerts "undefined undefined". Can anyone explain why my version doesn't work?
In JavaScript, this
is typically whatever comes before the .
in the function call. So the fact that you said dude.fullName()
is what caused this
in fullName()
to be set to dude
1.
In the second version in your question, you're not calling it the same way. You're calling personFullName()
without anything in front of it (which is correct, since it's no longer attached to a Person object). That means that this
ends up defaulting to the same value as window
. Since window
has no first
or last
properties set on it, this.first
and this.last
are undefined
.
To fix this, you can make your person be an argument to the personFullName() function:
function personFullName(person) {
return person.first + ' ' + person.last;
}
and then call it like
…
this.fullName = personFullName(this);
1: Note that the method has to be a property on the object for the this
binding to work. You can't just call object.someMethod()
and get have this
set to object
in someMethod
. In your code, the following would not work:
function Person(first, last) {
this.first = first;
this.last = last;
this.fullName = this.personFullName();
}
Uncaught TypeError: this.personFullName is not a function
Neither would this:
function personFullName() {
return this.first + ' ' + this.last;
}
function Person(first, last) {
this.first = first;
this.last = last;
}
var dude = new Person("Michael", "Jackson");
alert(dude.personFullName());
Uncaught TypeError: dude.personFullName is not a function
You can get around this restriction in any situation with the apply
helper method: this.fullName = personFullName.apply(this)
does what you expect the second version of your code to do and you can also call personFullName.apply(dude)
at any point and get "Michael Jackson"
back.
this
is the window in your personFullName
function as it wasn't called in the correct context. You can use apply to call it with the correct context without modifying the personFullName
function.
function personFullName() {
return this.first + ' ' + this.last;
}
function Person(first, last) {
this.first = first;
this.last = last;
this.fullName = personFullName.apply(this); // The magic
}
var dude = new Person("Michael", "Jackson");
alert(dude.fullName);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With