There is something I don\'t understand in javascript and broke down a sample problem to an essential case:
a = function () {
this.b = 5;
}
a.p
It's about resolving the this
value. This is resolved in the following way:
myObject.something();//this in something is myObject
window.something();//this is window
button.onClick=function();//this when button is clicked is button
How to solve it is already given, it's a common pitfall with passing callbacks like in the following example using setTimeout
var test = function () {
var me = this;// set reference to this
this.sayAgain=function(){
console.log("Hi, I am "+me.toString());
}
}
test.prototype.toString=function(){
return "test";
}
test.prototype.say = function () {
console.log("Hi, I am "+this.toString());
}
var t = new test();
setTimeout(t.say,50);//=window passing functon without ref to this
setTimeout(function(){
t.say();
},150);//=test passing ref with function
setTimeout(t.sayAgain,200);//=test using me as the saved this context
The second timeout passes a closure to setTimeout, if you're planning to pass the say callback hundreds of times but only create a couple of test object instances then the implementation of the last one (sayAgain) would perform slightly better.
This because you create a closure when you create the test instance but not when passing sayAgain as a callback, if you create many test instances and would not pass say
that many times then remove this.me and this.sayAgain from the function body and pass say
as a closure.
You can use Function.prototype.bind but it's not supported in IE < 8 and I am not sure if it'll create a closure as in my example using t.say
.
You need to call the method using the object to get the context right. So:
var e = function() { return d.c(); };
In newer browsers you can use the bind method to do the same:
var e = d.c.bind(d);
In jQuery for example there is the proxy method that you can use also in older browsers:
var e = $.proxy(d.c, d);
d.c
is like an unbound instance method. You can use Function.prototype.bind
to create a new function that's bound to d
(the first argument to .bind
is the this
argument):
var e = d.c.bind(d);
Or call e
with d
as the this
argument:
e.call(d);