[Proto-Scripty] Re: syntax for variable function name?

2010-04-15 Thread T.J. Crowder
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 executi

Re: [Proto-Scripty] Re: syntax for variable function name?

2010-04-14 Thread Walter Lee Davis
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?


function foo(){
alert("Meow");
}

function bar(){
  alert('Woof woof');
}

var x = 'foo';
window[x]();
window['bar']();




On Apr 14, 2:52 pm, Walter Lee Davis  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 at http://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.



[Proto-Scripty] Re: syntax for variable function name?

2010-04-14 Thread Pranav
Does this help?


function foo(){
alert("Meow");
}

function bar(){
   alert('Woof woof');
}

var x = 'foo';
window[x]();
window['bar']();




On Apr 14, 2:52 pm, Walter Lee Davis  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-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.