JackMahoney
JackMahoney

Reputation: 3433

Javascript global variable redefinition?

I have a questions regarding variable scope in Javascript. I have a series of scripts on a webpages loading at different times. I need a global object called MyVar for example to be accessible to them all. I want to avoid redefining it but I guess it has to be defined at some point by the first script. My question is is using var MyVar = MyVar || {} a solution?

Thanks

 /**
 * Script 1
 */


var MyVar = MyVar || {};
MyVar.config = {
    x : 2,
    y : 3
};


/**
* Script 2
*/

//is this correct?
var MyVar = MyVar || {};
//to which MyVar am I assigning the apple property?
MyVar.apple = 'red';

UPDATE

Great answers so far guys thanks.

One last part though, what is the second var statement doing when I repeat var MyVar = MyVar || {}; for the second time? Is it creating a new var in the global scope called MyVar that is assigned the value of the existing MyVar ?

Other posters are right to assume I have these scripts loading synchronously in <script> tags however due to division of labour I create the scripts then don't control when and how they are loaded so need a fool-proof method to create / utilize my MyVar object.

Thanks

Upvotes: 2

Views: 3739

Answers (4)

Christophe
Christophe

Reputation: 28174

This is how I do it:

window.myVar||(window.myVar={});

This way you are not re-declaring the variable if it already exists.

Upvotes: 0

ic3b3rg
ic3b3rg

Reputation: 14937

This is easy to test:

var MyVar = MyVar || {};
MyVar.config = {
    x : 2,
    y : 3
};

console.log(MyVar);

var MyVar = MyVar || {};
MyVar.apple = 'red';

console.log(MyVar);

Upvotes: 1

bfavaretto
bfavaretto

Reputation: 71939

I have a series of scripts on a webpages loading at different times

Is any of them loaded asynchronously? If it's just a series of <script> tags, they will be loaded synchronously, in sequence.

to which MyVar am I assigning the apple property?

If you declare MyVar on the global scope every time, there will be only one MyVar. The apple property will be created on the existing variable, if it exists, or in the empty object created with var MyVar = MyVar || {}; if it doesn't.

Bottom line: after the first var MyVar = MyVar || {};, following declarations will be ignored, and new properties will be appended to the existing variable. Just be careful not to overwrite existing properties.

Upvotes: 2

roryf
roryf

Reputation: 30170

Your code is correct and will probably work as expected, but bear in mind the scope in which MyVar is created. Assuming your files are as posted, they would create MyVar within the window scope (assuming a browser context). If one of them was wrapped in an anonymous function, as is common practice with the Module Pattern, MyVar would only be created within the scope of that function:

(function() {
    var MyVar = MyVar || {};
    // If MyVar doesn't already exist in the global context,
    // the current MyVar reference will only be scoped to this function.
})();

A better pattern to use is:

var MyVar = window.MyVar || (window.MyVar = {});

This will ensure it is always created, and referenced, from the global scope. You could even pass in the context in order to make future refactorings easier:

(function(context) {
    var MyVar = context.MyVar || (context.MyVar = {}));
})(window);

Upvotes: 2

Related Questions