26

When I call a function, a local scope is erected for that call. Is there any way to directly reference that scope as an object? Just like window is a reference for the global scope object.

Example:

function test(foo){
    var bar=1
    //Now, can I access the object containing foo, bar, arguments and anything
    //else within the local scope like this:
    magicIdentifier.bar
}

Alternately, does anyone have a complete list of what is in the local scope on top of custom variables?

Background: I'm trying to get down to a way of completely shifting to global scope from within a function call, the with statement is a joke, call works a little better, but it still breaks for anything declared in function scope but not in global scope, therefore I would declare these few cases in global scope, but that requires me to know what they are. The IE function execScript makes a complete shift, but that only solves the problem for IE.

Note: To anyone loading JavaScript dynamically, setTimeout(code,1) is a simple effective hack to achieve global scope, but it will not execute immediately.

aaaaaaaaaaaa
  • 3,630
  • 1
  • 24
  • 23
  • If you need to access the object containing the `foo` argument inside the function why not directly pass this object as argument? – Darin Dimitrov Apr 08 '10 at 13:53
  • @aaaaaaaaaaaa did you ever find a viable solution for this? I'd be very interested, especially a solution that works for block-scoped variables as well WITHOUT using `eval()` or `new Function()`. – Brandon McConnell Jun 03 '21 at 13:37

5 Answers5

16

No, there's no way to reference the variable object of the execution context of a function binding object of the variable environment of the execution context (that's what that thing is called [now; hence the strikethrough]; details in §10.3 of the specification). You can only access the limited view to it you get with arguments (which is very limited indeed).

Usually when I've wanted to do this, I've just put everything I wanted on an object and then used that (e.g., passed it into a function). Of course, any functions created within the context have access to everything in scope where they're created, as they "close over" the context; more: Closures are not complicated.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Wow, those specs are really a pain to read. In any case, as far as I can tell, they seem to suggest that the only local variables apart from parameters and the defined locals are arguments and length. That should get me moving, thank you. I'm building a library, and the first function I'm making is a consistent version of setInterval, that is what this is for. Everything seems to grow so much more complicated when you have so supply a shiny abstractioned interface. – aaaaaaaaaaaa Apr 08 '10 at 15:48
  • @eBusiness: Yes, yes it does. :-) Don't forget any named functions declared within the function, those are in-scope symbols as well. – T.J. Crowder Apr 08 '10 at 16:03
11

I know this is hugely late, and you're probably not even slightly interested any more, but I was interested in the feasibility of this too and you should be able to make a work around of some sort using:

(function(global) {
    var testVar = 1;

    global.scope = function(s) {
        return eval(s);
    }
})(this);

then running:

scope('testVar'); // 1

returns the variable from within the closure. Not particularly nice, but theoretically possible to wrap that in an object, perhaps using some validation and getters and setters if you needed?

Edit: Having re-read the question, I assume you'd want to access it without having to specify a function in the scope itself, so this probably isn't applicable. I'll leave this here anyway.

Dom Hastings
  • 326
  • 4
  • 14
1

Certain versions of Netscape had a magic property in the arguments object that did what you're looking for. (I can't remember what it was called)

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • `arguments` is an variable containing all the arguments passed to the current function. – nickf Apr 08 '10 at 13:55
  • 1
    @nickf: I realize that. In certain versions of Netscape, it had a special proeprty that referred to the variable scope. – SLaks Apr 08 '10 at 13:57
  • 1
    @nickf: I misread it at first, too, but knowing SLaks I gave it a second reading and realized what he meant. :-) – T.J. Crowder Apr 08 '10 at 13:58
  • Interesting, but I'm afraid what is available in "Certain versions of Netscape" just won't do in modern web development ;-) – aaaaaaaaaaaa Apr 08 '10 at 14:24
  • It might still exist in Firefox. However, you're right; this doesn't actually help you. – SLaks Apr 08 '10 at 14:27
0

What about something like this?

<script type="text/javascript">
    var test =  {
        bar : 1,
        foo : function () {
            alert(this.bar);
        }
    }

    test.foo();
</script>
Ivo Sabev
  • 5,230
  • 1
  • 26
  • 38
-4

You don't need a keyword to reference a variable in the local scope, because it's the scope you're in.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 1
    Iterate over every single variable that exists in the current scope? That doesn't sound Javascriptic (or whatever the Javascript analog of the word "Pythonic" is) to me. – Matt Ball Apr 08 '10 at 14:04
  • 2
    Not having an object that references local variables sounds Un-Javascriptic to me. I don't need it but I'd expect it to exist, JavaScript seems to have objects for almost everything and be all about objects. – Rolf Dec 05 '13 at 17:16
  • @Rolf I must respectfully disagree. It doesn't feel un-JS-y to me. Such an object is also unnecessary. When you really, _really_ need to dynamically access a variable – and you're really, _really_ sure that you shouldn't be using a `{}` (a dedicated object) – there's always `eval` to fall back to. – Matt Ball Dec 05 '13 at 18:11