tags:

views:

87

answers:

3

Hi,

I'm a bit confused by JavaScript's window object. For starters, consider the following two declarations:

var imglobal = "I'm Global";

window.imglobal = "I'm Global";

As far as I understand it, this would be exactly the same (is it?) It can be accessed as "imglobal" or "window.imglobal" in both cases. I don't understand why, var declares local variables, the following doesn't work:

function imafunc() {
  var imavar = "I'm a variable";
  window.alert(imafunc.imavar);
}

So why does the following?

var imavar = "I'm a variable";
window.alert(window.imavar);

I stumbled across this when using GWT; it appears one always has to refer to the window object ($wnd there) explicitly there, probably because it's not the "real" window object but some kind of sandbox.

It gets even more confusing with functions, I know three ways to declare them:

var myfunc = function() { window.alert("Hello, World!"); }

window.myfunc = function() { window.alert("Hello, World!"); }

function myfunc() { window.alert("Hello, World!"); }

Is there any technical difference between these three approaches?

+2  A: 

There is no differences between global variables and window properties (at least not that much ;))

The last scope in the scope chain of each function is the window object. Therefore every property of the window object is available in any function without referencing window explicitly.

Update:

I don't understand why, var declares local variables, the following doesn't work:

 function imafunc() {
   var imavar = "I'm a variable";
   window.alert(imafunc.imavar);
 }

You cannot access imafunc.imavar because it is not a property of the function. imavar is a property of the activation object, that gets created upon execution of the function and is the "first scope" in the scope chain. You cannot access it directly.

Felix Kling
This explains why "window" is optional, thanks.
theone
+1. Pretty close. It would be more accurate to say that the last object on the scope chain is always the *global* object; in browsers, `window` acts as the global object but this isn't true in other environments.
Tim Down
@Tim: Thank you for clarifying. I knew about the *global* object, but I was not 100% sure.
Felix Kling
A: 

Btw, to make your function work you have to make imavar a property of the function:

function imafunc() {
  this.imavar = "I'm a variable";
  window.alert(imafunc.imavar);
}

The differnt between your three functions is that only the third can called before the declaration in the code, the others are only available till the assigned to variable, cause they are nameless Function Expressions.

myfunc1() and myfunc2() //throws an error cause it isn't declared right now
myfunc3()  will alert(Hello, World!)

var myfunc1 = function() { window.alert("Hello, World!"); }
window.myfunc2 = function() { window.alert("Hello, World!"); }
function myfunc3() { window.alert("Hello, World!"); }

myfunc1()//will alert(Hello, World!)
myfunc2()//will alert(Hello, World!)

http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/

eskimoblood
Thank you for that clarification regarding functions!My confusion with imavar is that "var imavar" would declare "window.imavar" outside a function, but "var imavar" inside "myfunc" wouldn't declare "myfunc.imavar".
theone
That looks wrong. The first part of your answer looks like you're saying that inside a function, `this` is a reference to the function object itself, which is generally not the case.
Tim Down
Tim is right, `imafunc.imavar` will not be defined. Very often, `this` refers to the `window` object in a function (depends on "who" called the function).
Felix Kling
Ok you're right when you simply call imafunc() this is window in cause of the scope chain.
eskimoblood
+4  A: 

About your observation:

I stumbled across this when using GWT; it appears one always has to refer to the window object ($wnd there) explicitly there, probably because it's not the "real" window object but some kind of sandbox.

The reason you will always need to prefix your variables and functions with $wnd in GWT JSNI is to ensure that you are accessing the variable from the window scope (host page). This is because JSNI is run inside an iframe, hence any variable without the $wnd qualifier would resolve within the scope of the iframe and not the window scope, which you intended.

Ashwin Prabhu