Hi again Doug,

> > But, my question is, is there a way I can do some type of alert() and
> > have it print out what scope it is executing in?
>
> I don't know of a reliable way to do that, no.

But if you're using Firefox, it looks like the latest Firebug[1] now
displays the scope chain on the watch panel automagically when you're
stepping through code.  VERY cool. :-)

[1] http://www.getfirebug.com
--
T.J. Crowder
tj / crowder software / com
Independent Software Engineer, consulting services available


On Feb 11, 11:39 am, "T.J. Crowder" <t...@crowdersoftware.com> wrote:
> Hi Doug,
>
> > I don't really understand, for example why, if there is a variable
> > window.myvar, some Javascript code would not be able to access it...
>
> As far as I know, all code within the same document can access that
> property; it is global to the document because it's a property of the
> "window" object, which is global to the document.  Offhand, I can only
> think of two situations where it would be in accessible:  1. If you're
> dealing with frames or iframes, those are in separate documents and
> they each get their own copy of "window" with its own properties; 2.
> If "window" has been hidden by another declaration called
> "window" (e.g., a function with "var window" in it, or someone using
> 'with'), which would be a Bad Idea(tm).
>
> > But, my question is, is there a way I can do some type of alert() and
> > have it print out what scope it is executing in?
>
> I don't know of a reliable way to do that, no.  You can get hints at
> it, as with seasoup's note about arguments.callee, but that won't help
> you if you're executing code in the global scope or within an 'exec'.
> But good news:  You can always tell by looking at the source, because
> in JavaScript, scope is dictated by program structure; it's not
> determined at runtime.
>
> Most of us are familiar with the concept of globals and locals:
>
> * * * *
>
> var a = "h";
>
> function doSomething() {
>
>     // 'a' is a global, so this function can see it
>     alert(a);
>
> }
>
> doSomething();  // alerts "h", the current value of 'a'
> a = "j";
> doSomething();  // alerts "j", the current value of 'a'
>
> * * * *
>
> JavaScript takes this to the logical next step:  Functions declared
> within a scope inherit that scope and all of its parent scopes, in a
> chain:
>
> * * * *
> var a = "h";
>
> function outermost() {
>     var b = "e";
>
>     function middle() {
>         var c = "ll";
>
>         function innermost() {
>             var d = "o";
>
>             alert(a + b + c + d);
>         }
>
>         innermost();
>     }
>
>     middle();
>
> }
>
> outermost();  // alerts "hello"
> * * * *
>
> Cool, huh?  Each unqualified reference is resolved by checking it
> against the innermost scope and, if not found there, the next scope up
> in the chain -- in this case, innermost -> middle -> outermost ->
> global.  To know what the scope chain looks like, we need only look at
> where the functions are defined.  This is the crucial bit:  It's where
> they're defined, not where they're called.
>
> The program structure tells us what variables are in scope for which
> functions, but as always, the *values* of those variables is
> determined at runtime.  It's easy enough to realize that calling
> 'outermost' above gives us "hello" and that that changes if we change
> 'a':
>
> * * * *
> outermost(); // alerts "hello"
> a = "j";
> outermost(); // alerts "jello" (mmmmmm, Jello)
> * * * *
>
> Simple enough, you've changed a global used by one of the inner
> functions.  We can also do the same thing using a parameter to
> 'outermost':
>
> * * * *
>
> function outermost(a) {
>     var b = "e";
>
>     function middle() {
>         var c = "ll";
>
>         function innermost() {
>             var d = "o";
>
>             alert(a + b + c + d);
>         }
>
>         innermost();
>     }
>
>     middle();
>
> }
>
> outermost("h"); // alerts "hello"
> outermost("j"); // alerts "jello"
>
> * * * *
>
> Note we don't have a global 'a' anymore; it's a parameter of
> 'outermost'.  Doesn't matter, parameters go on the scope chain just
> like local variables do.
>
> Where people start to get a bit glassy-eyed is when we start passing
> around function references, which we do all the time in JavaScript.
> Consider this:
>
> * * * *
>
> function outermost(a) {
>     var b = "e";
>
>     function middle() {
>         var c = "ll";
>
>         function innermost() {
>             var d = "o";
>
>             alert(a + b + c + d);
>         }
>
>         innermost();
>     }
>
>     return middle;
>
> }
>
> * * * *
>
> Note that 'outermost' now returns a reference to the 'middle'
> function, it does *not* call it.  No alert occurs if we call
> 'outermost'; it occurs when we call the function returned by
> 'outermost'.  Now, what do we see when we do this:
>
> * * * *
>
> var f1 = outermost("h");
> f1();
>
> * * * *
>
> We call 'outermost' with an "h", and it returns a function reference
> we store in 'f1', and then we call the function.  Well, you probably
> said it alerts "hello" -- and you'd be right!  How 'bout this:
>
> * * * *
>
> var f1 = outermost("h");
> var f2 = outermost("j");
> f1();
> f2();
>
> * * * *
>
> What do we see when 'f1' is called?  And 'f2'?  The answers, as you
> will have realized, are of course "hello" and "jello", respectively.
> This is because a function reference includes the execution context of
> that function, including the parameters and locals.
>
> "Now hang on a minute," you're saying, "that parameter I passed into
> 'outermost' the first time is gone by the time I call 'f1'!  How can
> 'f1' still reference it?!"  The answer is:  The parameter is not
> gone.  It would be, if there were no outstanding references to it, but
> there *is* an outstanding reference to it -- our 'f1' variable refers
> to it.  That 'a' parameter lives on as a property of an object (called
> the "variable object") within the execution context we're referencing
> with our 'f1' variable.  It will continue to live on until/unless we
> release it.  (The variable object has no symbol associated with it,
> it's anonymous within code.  With one exception:  The topmost variable
> object is the global object, which in browser-based implementations is
> known as "window" [more technically, it has a property called "window"
> that refers to it].)
>
> This execution context and variable object stuff is why JavaScript
> functions are technically termed "closures" (a term from mathematics
> basically meaning a function that has data bound to it).
>
> I've done a couple of blog posts on the subject -- with diagrams --
> which can be found here; they may be 
> useful:http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.htmlhttp://blog.niftysnippets.org/2008/03/closures-by-example.html
>
> HTH,
> --
> T.J. Crowder
> tj / crowder software / com
> Independent Software Engineer, consulting services available
>
> On Feb 11, 1:21 am, doug <douglass_da...@earthlink.net> wrote:
>
> > I have read about Javascript and scope and I still don't really
> > understand it completely, particularly when it comes to Ajax.Updater.
>
> > I don't really understand, for example why, if there is a variable
> > window.myvar, some Javascript code would not be able to access it, and
> > instead it would be undefined for that code.   I was thinking
> > window.myvar was "global"
>
> > But, my question is, is there a way I can do some type of alert() and
> > have it print out what scope it is executing in?
>
> > thanks,
> > -d
>
>
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to