5

I've gotten into the habit of adding the following at the top of all my functions:

var local = {};

That way, I explicitly scope all my variables. For example:

for (local.i=0; local.i<x; local.i++) {} // local scope: good!
for (i=0; i<x; i++) {} // accidental global scope: bad!

Q: Is there a way to change the Function prototype to include var local={}; as part of it's definition? That way I can assume that "local." means explicitly in the local scope.

6
  • 8
    I'm not really sure how this makes your life easier than explicitly using the var keyword. In either instance you need to remember to use a prefix, why not stick with the built in one? Commented Dec 26, 2013 at 19:52
  • Well, you can always try to use source code transformators, such as esprima. But I doubt you can do anything like this without code transformation. Commented Dec 26, 2013 at 19:52
  • 6
    How about just enabling strict mode with "use strict"? That way, you get an error when you accidentally leak a variable into the global scope. Commented Dec 26, 2013 at 19:53
  • 2
    Wrap your for loop with a function, and don't forget the var keyword. Commented Dec 26, 2013 at 19:55
  • 2
    "...the following at the top of all my functions" : this shouldn't be needed as JavaScript variables have function scope (if you use var keyword). Using var is much more readable and "standard". Commented Dec 26, 2013 at 19:59

2 Answers 2

3

The answer is no, you can't implicitly add a variable declaration and initialize it in every function scope (thank goodness). You need to manage your variable scopes manually, employing analysis tools when/if desired.

Imagine for a moment if this was possible. Any code you load could potentially corrupt any other variable scope, effectively defeating the purpose of scoped variables.

The Function.prototype will not help because prototypal inheritance has nothing to do with variable scope.

Your trick to protect i by putting it in a local object doesn't solve anything. It just moves the problem from the i variable to the local variable, and still doesn't keep you from using i instead of local.i.

While including "use strict"; can help by providing helpful error messages, you need to keep in mind that it changes behavior in some situations that can break code.

Sign up to request clarification or add additional context in comments.

Comments

1

No, you can't do this. You can't inject code into arbitrary functions and mess around with their local scope by changing the Function.prototype, and that's a good thing.

Besides, how would you enforce using the local object for local variables anyway? And how would you allow variable lookups through parent scopes, such as in:

function f() {
    var a = 5;
    return function g(b) {
        return a + b;
    };
 }

In your solution, you'd have a local object in the f and g functions, but the local variable in g would hide the parent's variable...

function f() {
    var local = { a : 5 };
    return function g(b) {
        // This declaration hides the parent's declaration
        var local = { b : b };
        // How would local.a be found?
        return local.a + local.b;
    };
 }

There's a much simpler solution to your original problem though: just enable strict mode with "use strict". That way, you get an error when you accidentally leak a variable into the global scope. For example, your second sample would throw a ReferenceError when it tries to access the undeclared i variable (instead of creating a new global variable).

Do note that strict mode goes further than just preventing accidental global variables, read up on it so you understand the consequences!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.