What does 'this' keyword refer to when used in gloabl object?
Let's say for instance we have:
var SomeGlobalObject =
{
rendered: true,
show: function()
{
/*
I should use 'SomeGlobalObject.rendered' below, otherwise it
won't work when called from event scope.
But it works when called from timer scope!!
How can this be?
*/
if(this.rendered)
alert("hello");
}
}
Now if we call in an inline script in the HTML page:
SomeGlobalObject.show();
window.setTimeout("Msg.show()", 1000);
everything work ok.
But if we do something like
AppendEvent(window, 'load', Msg.show);
we get an error because this.rendered is undefined when called from the event scope.
- Do you know why this happens?
- Could you explain then if there is another smarter way to do this without having to rewrite every time "SomeGlobalObject.someProperty" into the the SomeGlobalObject code?
Thanks!
AppendEvent is just a simple cross-browser function to append an event, code below, but it does not matter in order to answer the above questions.
function AppendEvent(html_element, event_name, event_function)
{
if(html_element.attachEvent) //IE
return html_element.attachEvent("on" + event_name, event_function);
else
if(html_element.addEventListener) //FF
html_element.addEventListener(event_name, event_function, false);
}
A simple way to describe what happened:
'this' always refers to the invoker of the function.
So take the offending case:
Event handling is invoked by the window. So 'this' becomes window and
is undefined.
bind() will quickly become your best friend :-)
As an aside
will run a little quicker if you supply the function object directly
This is because the first syntax requires eval() of the string - basically compiling - before it can be invoked
Do this
Javascript supports dynamic scoping. So SomeGlobalObject will be available to the function declared inline always.
When you reference a function that is a method of an object, you're detaching it from that object and
this
will no longer be a reference to the object.The easiest solution is to wrap it in an anonymous function:
There's also the
bind
method available to functions in ECMAScript 5th Edition implementations, which allow you to do this:The JS framework, Prototype, provides this method to current JS implementations too. The code (thanks @bobince):
The
this
keyword always refers to the calling object. In the first example, SomeGlobalObject is the caller.I believe you would need to do something like
AppendEvent(window, 'load', function() { SomeGlobalObject.show() })