I'm trying to understand the difference between foo.bar()
and var fn = foo.bar; fn();
I've put together a little example, but I dont totally understand why the failing ones actually fail.
var Dog = function() {
this.bark = "Arf";
};
Dog.prototype.woof = function() {
$('ul').append('<li>'+ this.bark +'</li>');
};
var dog = new Dog();
// works, obviously
dog.woof();
// works
(dog.woof)();
// FAILS
var fnWoof = dog.woof;
fnWoof();
// works
setTimeout(function() {
dog.woof();
}, 0);
// FAILS
setTimeout(dog.woof, 0);
Which produces:
On JSFiddle: http://jsfiddle.net/D6Vdg/1/
So it appears that snapping off a function causes it to remove it's context. Ok. But why then does (dog.woof)();
work?
It's all just a bit confusing figuring out whats going on here. There are obviously some core semantics I'm just not getting.
The problem is with context and the this
keyword.
Functions don't inherently "belong" to an object. For example, I can create a cat object and copy the woof function over:
var cat = {
bark: "meow",
woof = Dog.prototype.woof
};
Now cat.woof
will give me "meow". Because of this flexibility of functions to be copied and re-assigned, var fnWoof = dog.woof;
disassociates fnWoof
from dog
- it has no context. Therefore the context, and the this
keyword, defaults to window
. Since window
doesn't have a bark
property, you get undefined
.
If you give window a bark property:
window.bark = "Arf";
Then your code will work (although erroneously):
fnWoof(); // "Arf"
To make it work as expected, you can pass in the context explicity:
fnWoof.call(dog);
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