views:

389

answers:

3

When a function is attached to an object and called:

function f() { return this.x; }
var o = {x: 20};
o.func = f;
o.func(); //evaluates to 20

this refers to the object that the function was called as a method of. It's equivalent to doing f.call(o).

When the function is called not as part of an object, this refers to the global object. How do I check if a function is being called from a non-object context? Is there any standard keyword to access the global object? Is the only way to do it something like this?

globalobj = this;
function f() { if (this == globalobj) doSomething(); }

Note: I have no particular use case in mind here - I actually am asking about this exact mechanism.

+4  A: 

The global object is actually the window so you can do

if (this === window)
Greg
True at least if the script is running in a browser (since javascript now can be run in other places it might not be a universal truth)
some
is this a standard across browsers?
Claudiu
That depends on the browsers implementation of JavaScript engine, but that is mostly the case.
fasih.ahmed
It's true for FF, IE, Opera and Chrome on Windows. A little more info: http://www.quirksmode.org/js/this.html
some
"Objects and this", "In a simple function call, this is set to the Global Object (aka window), which is not very useful.", http://javascript.crockford.com/survey.html
some
In the same document, "Global object": "In the web browsers, window and self are members of the Global Object which point to the Global Object, thus giving an indirect way of addressing it."
some
A: 

RoBorg's answer is conceptually correct -- except window is only available in the context of the browsers main thread (so this necessarily excludes worker threads and the like, as well as any non-browser hosted JS, which is getting less and less uncommon).

Your safest bet is basically what you had above, but you should use var and === as it is possible for the interpreter to optimise such accesses more completely.

olliej
+1  A: 

The below should work since using Function.call with a value of null will invoke it in the global scope.

this === ((function () { return this; }).call(null))

A simpler variant,

this === (function () { return this; })()

will also work, but I think the first makes the intent clearer.

Mike Samuel