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" <[email protected]> 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 <[email protected]> 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 [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~----------~----~----~----~------~----~------~--~---
