onClick Function "this" Returns Window Object
I've come across a head scratching issue with my JavaScript application.
If I write an element like this:
<li onClick="alert(this.tagName)"></li>
I get "LI."
However if I do this:
<li onClick="foo()"></li>
Where "foo()" is:
function foo(){ alert(this.tagName); }
I get "undefined."
I am away how "this" is supposed to work in regards to attached functions. But, I am baffled because "this" is not picking up the element, but apparently defaulting to "window." I can't figure out why this is happening.
Does anyone have an explanation?
Solution 1:
That's because you aren't passing a reference to this in the JavaScript function call. this in the JavaScript function doesn't refer to the same object as in the onClick example. Try this instead:
<li onClick="foo(this)"></li>
function foo(item){ alert(item.tagName); }
Solution 2:
In an inline listener:
> <li onClick="alert(this.tagName)"></li>
The onclick attribute value is effectively wrapped in a function and called with the element set to this, e.g.
function anon() {
/* attribute value */
}
anon.call(element);
When you put a function in the body, you are essentially getting:
function anon() {
foo();
}
Here, this
within anon
will be the element, but since foo
is called without setting this
, it will be undefined. In non-strict mode, this
will default to the global object (window
in a browser). In strict mode, this
inside foo
will be undefined.
One solution is to pass an element reference to the function:
<li onclick="foo(this)" ... >
then in the function:
function foo(callingElement) {
...
}
or even:
<li onclick="foo.call(this)" ... >
function foo() {
var callingElement = this;
}