'this' Returning Either 'Object' Or 'Window' Inside The Same Object
Solution 1:
Question is, why does the first 'this' output 'Object' and the second one 'Window'?
this
is set primarily by how a function is called (for now*), not where it's defined. In the first case, the way you're calling the function is through an object reference (positionDetector.detectPosition()
), and so the JavaScript engine sets this
to be the object you used as part of the expression making the call. In the second case, the function isn't being called as part of an expression retrieving the function reference from an object property, so this
takes its default value (the global object in loose mode, undefined
in strict mode). Here's a simpler example:
var obj = {
foo: function() {
console.log(this);
}
};
var f = obj.foo;
obj.foo(); // `this` is `obj` during the call
f(); // `this` is not `obj` during the call
To solve it, you could use Function#bind
to use a specific this
value during the callback:
navigator.geolocation.getCurrentPosition(this.locationHandler.bind(this))
Function#bind
creates a function that, when called, will call the original file with a specific this
value (and any optional arguments you provide).
More about this
(on my blog):
* "for now": ES6 introduces CoffeeScript-style arrow functions, which have a this
value that's set by the context in which the function is created. That wouldn't really help you here, but it makes my usual "...is set primarily by how a function is called..."* statement no longer true. :-)
Solution 2:
Because this
depends on the caller. The caller to this.locationHandler
is navigator.geolocation.getCurrentPosition(callback)
and it calls the function like callback()
, notice, there is no dot in that call, meaning there is no value for this
. The solution is to set this
permanently using bind
:
navigator.geolocation.getCurrentPosition(this.locationHandler.bind(this))
Remember, general rule: no dot, no this
, unless you used call
or apply
to call the function, or bind
to set the value of this
forever.
Solution 3:
Both T.J. Crowder & elclanrs are right.
As a brief explanation: "this" refers to object context (A.K.A. scope) and it does not work exactly as you expected in javascript unfortunately ,
- detectPosition() is called in the context of PositionDetector by you.
- locationHandler() is called in the context of window which is the global object and the event originator.
IMHO this situation renders Javascript stupid. There are two methods to overcome this effect. First is the "bind" method as they have shown. The second one is the magical "closure" generation.
Post a Comment for "'this' Returning Either 'Object' Or 'Window' Inside The Same Object"