4

I've got a problem of having code variable names conflicting each other, ie;

<script type="text/javascript">var a = "hello"; </script>
<script type="text/javascript">alert(a);//this works, when I want 'a' not to exist </script>

Are closures the only option?

Coming from a c# background, its like constructing an unreferenced instance of a delegate, then calling it inline, which seems a bit messy

(function(){var a = "hello";})();
(function(){alert(a);})();//yes! working as expected

5 Answers 5

6

Using a (immediately self-executing) function to create a new scope is indeed the way to go.

This also has the advantage that you can ensure that certain variables have certain values. When using jQuery, the following is common for example:

(function($, window, undefined) {
    // ...
})(jQuery, this);

Unless you have tons of functions with only a single statement in each (like in your example) it is also perfectly readable.

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

Comments

5

Yes, closures are your only option. In browsers all JavaScript files get put into the same global scope.

IIFE's are very common place in JavaScript; I wouldnt' call them messy.

Comments

2

Javascript only has function scope, unlike C# which has block scope. The following code is valid javascript and C#:

var x = 2;
while(true) {
    var y = 3;
    break;
}
//y is not accessible here in C#, but is in javascript

The only way to create a new scope is to create and execute an anonymous function.

Comments

0

For short, inline stuff then you're best to use the module pattern to create a closure and therefore emulate private variables.

(function(){
    var a....
    })();

A better long-term approach is to use objects as namespaces.

var NS = {};
NS.a = 1;

Comments

0

Just to provide a different perspective. It is possible to write code without using closures, and maintain (arguably) safe global variable scope.

  1. Define a single object, to use as a namespace, with a suitably unique name (e.g. MyAppContext) that will have global scope, and if you need to define global-like variables only for use in your application only, attach them to this object.

    MyAppContext.appTitle = 'Application Title';

  2. At the start of your script where you create MyAppContect make sure it doesn't aleady exist.

  3. Make sure that all of your function-scoped variables use the var keyword so you know you're not referencing a global value.

Obviously this approach opens up a risk that you forget to define some of your function variables with var. JSLint can help you in respoect of this this.

I am happy to retract this answer if I start getting flamed, but I believe it is a workable alternative approach to using closures. And hey! it's old skool

I also agree that the use of closures is safer, but thought this might interest you.

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.