I have this simple code :
var o = {
a: 1,
b: 2,
f1: function ()
{
alert(this.b);
}
}
var o2 = {
a: 11,
b: 22,
f2: function (j)
{
j();
}
}
But running this code :
o2.f2(o.f1)
yields undefined. ( while im expecting "22" as a result)
Now, I know that the context has gone somewhere. and hence If I change the code in o2
to :
f2: function (j)
{
j.apply(this);
}
It does work obviously.
But my question is :
I don't understand : when j()
is running , there is a b
property in the o2
object.
What am I missing ?
jsbin
The this keyword of the clickMe arrow function refers to the global object, in this case the window object. So, this. position and this. color will be undefined because our window object does not know anything about the position or the color properties.
You can't change what this refers to from inside the function. However, you can call a function in a specific context - so that this refers to a specific object - by using call or apply . Show activity on this post. Note "is immutable".
You can use addEventListener to pass this to a JavaScript function.
What is context? Context is always the value of the this keyword which is a reference to the object that “owns” the currently executing code or the function where it's looked at. We know that window is a global object in the browser so if we type this in the console and it should return window object, which it does.
I found Crockford had an excellent description of the way this works. Functions in JavaScript can be invoked in 4 styles :
I might be getting the exact names wrong there, but the spirit is the same. You should definitely get the book "JavaScript: The Good Parts" if you don't have it.
So anyway - on to your question. The key thing is that the value if "this" is dependant on which style you use.
// function invocation style,
var f = function() { console.debug(this); }
f(); // "this" is bound to the global object.
// "method" invocation style
var obj = {
f: function() { console.debug(this); }
};
obj.f(); // "this" is bound to "obj", the object on which the function was invoked
// so important bit is :
var f = obj.f;
f(); // "this" is global object
obj.f() // "this" is obj
In your example you are losing "this" because of the way you are invoking the function.
If you do it like as follows,
function will be called in o2 context
var o2 = {
a: 11,
b: 22,
f2: function (j){
this.temp = j;
this.temp();
}
};
also these will work too:
f2: function (j){
j.apply(this);
}
f2: function (j){
j.apply(o2);
}
Otherwise you call it just like an ordinary function out of context.
j Is ripped out of its context and you did no tricky closures on it(which is not your intent) so for making "this" work in it you need a scope. The this scope in your question for j is window, which has no "b" in it therefore you get an "undefined".
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