Hi, > So if I'm inside an anonymous function, can I > still use window...
Yes if the functions in question are declared at global scope (as in Pranav's example), no if they aren't (you can access `window`, but the functions won't be properties of it). So this would work: function foo() { } var x = 'foo'; window[x](); but this would not: function bar() { function foo() { } var x = 'foo'; window[x](); // fails, no "foo" prop on `window` } The reason it works at global scope (technically, in the global execution environment) is that the global execution environment has a unique feature: `var`s and function declarations at global scope end up as properties on the global object, which is accessible as `window` in browsers (and accessible in a similar way in non-browser environments). Although there is (at least conceptually) a similar object in the second example that has a "foo" property, we have no way of accessing that object directly. If you're interested, I've given a very high-level overview of the details below (there's still a fair bit of hand-waving; the ECMAScript spec is 252 pages long for a reason). So, the global execution environment has a unique feature that lets us get at the variables defined at global scope. Before we can talk about how that happens, we have to talk about "variable environment" object: Consider this code (which is at the top level, not in any function): * * * * var global = "Hi"; function foo() { var fooLocal = "there"; alert(global); // "Hi" alert(typeof bar); // "function" alert(typeof barLocal); // "undefined" because it's not in scope function nifty() { var niftyLocal = "!"; alert(global + " " + fooLocal + niftyLocal); // "Hi there!" } } function bar() { var barLocal = "flibbergibbet"; } * * * * You can think of the above is a bunch of boxes containing boxes: +-- window -------------------------------+ | | | +-- foo ------------------------------+ | | | | | | | +-- nifty ------------------------+ | | | | | | | | | | | | | | | | +---------------------------------+ | | | | | | | +-------------------------------------+ | | | | +-- bar ------------------------------+ | | | | | | +-------------------------------------+ | | | +-----------------------------------------+ Without delving too much into the mechanics of it, when you call `foo` (for instance), the interpreter creates a "variable environment" object for the call. This object gets assigned properties for all of the `var`s in the function, all of the named functions declared within the function, all of its declared arguments, and the `arguments` property. So if you call `foo`, its variable object would have these properties: - arguments - fooLocal - nifty If you call `nifty`, its variable object would look like this: - arguments - niftyLocal Unqualified references within the function are resolved by looking them up on the variable object. So within `nifty`, if I refer to `niftyLocal`, it's found on `nifty`'s variable object. But what if I refer to `fooLocal`? It's not on `nifty`'s variable object, and so the interpreter looks for the next variable object in the chain, which is `foo`'s. And there's `fooLocal`, so we're done. If `nifty` refers to `global`, it's not found on `nifty`'s variable object, and it's not found on `foo`'s, so how does it get resolved? It gets resolved because functions aren't the only things with variable objects; the master call to the global code that ran the page also has a variable object, and so the chain continues with that one. Since that variable object has `global` on it, it's resolved. E.g., when calling `nifty`, its identifier resolution chain looks like this: `nifty`'s variable object -> `foo`'s variable object -> the global environment's variable object (It's actually a bit more complicated than that, but the complications are not relevant here.) I give a marginally better picture in my blog post here.[1] Now, these variable objects are anonymous (in fact, in any given implementation they may just be conceptual, not real). There's no way to get a reference to the variable object for a given call to `foo`, it's just not a specified part of the language. (The `arguments` object gives you a very, very limited view into the variable object, but that's it.) EXCEPT! Remember that unique feature of the global execution environment? Here it is: Its variable object effectively *is* the global object. And in browsers, the global object has a property called "window" that it uses to refer to itself. And so we have direct access to the variable object for the global execution environment, which makes it unique. (This is all defined by a constellation of sections in the spec, but the most relevant are 10.4.1 and 10.2.3.) So when we do this at global scope: function foo() { } ...we create a property on the global environment's variable object called "foo", and since that object effectively is the global object, and the global object effectively has a name ("window"), we can refer to it as window["foo"]. But we can't do that to refer to `foo` here: function bar() { function foo() { } } ...because the variable object for the call to `bar` doesn't have a name and we have no way of accessing it directly. [1] http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html HTH, -- T.J. Crowder Independent Software Consultant tj / crowder software / com www.crowdersoftware.com On Apr 14, 10:05 pm, Walter Lee Davis <wa...@wdstudio.com> wrote: > Yes it does. Thanks. So if I'm inside an anonymous function, can I > still use window, or do I need to figure out a scope variable to where > I am and use that? > > Walter > > On Apr 14, 2010, at 4:33 PM, Pranav wrote: > > > > > Does this help? > > > <script type="text/javascript"> > > function foo(){ > > alert("Meow"); > > } > > > function bar(){ > > alert('Woof woof'); > > } > > > var x = 'foo'; > > window[x](); > > window['bar'](); > > > </script> > > > On Apr 14, 2:52 pm, Walter Lee Davis <wa...@wdstudio.com> wrote: > >> In PHP, there's this handy construct where you can use the value of a > >> variable as the name of a function, so when you call $foo() you would > >> call the real function bar() or baz(), depending on the value of $foo > >> in the current scope. > > >> Is there an equivalent in JavaScript, and if so, what is it? I am > >> looking at taking the return of an Ajax callback and using it to > >> decide whether to add or remove a classname from an element. > > >> Thanks in advance, > > >> Walter > > > -- > > You received this message because you are subscribed to the Google > > Groups "Prototype & script.aculo.us" group. > > To post to this group, send email to > > prototype-scriptaculous@googlegroups.com > > . > > To unsubscribe from this group, send email to > > prototype-scriptaculous+unsubscr...@googlegroups.com > > . > > For more options, visit this group > > athttp://groups.google.com/group/prototype-scriptaculous?hl=en > > . -- You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group. To post to this group, send email to prototype-scriptacul...@googlegroups.com. To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en.