3

Possible Duplicate:
What does “var FOO = FOO || {}” mean in Javascript?
Javascript - Can you add condition to variable declaration

I believe this has to do with scoping, and not redefining scope. I see a lot of this in popular javascript frameworks:

var something = something || {};

Is that to do with not accidentally redefining a top-level variable?

Community
  • 1
  • 1
larryq
  • 15,713
  • 38
  • 121
  • 190

8 Answers8

5

You are correct. If the variable already exists (ours or not), don't change it. If it doesn't exist, let's create a new one.

Some Guy
  • 15,854
  • 10
  • 58
  • 67
  • 1
    Using the `var` keyword, a new object will always be created. – js1568 Aug 27 '12 at 17:11
  • @js1568 That does seem logical, but it isn't true. [This demo](http://jsfiddle.net/3RfYV/) logs the original object for me. Basically it means that a new variable *will* be created, but its value will be the same as the old one. – Some Guy Aug 27 '12 at 17:13
  • Your example has the same scope for each statement, so you are not changing anything. Let me show how a global variable `something` will not be affected by a local variable `something`. Showing that they are TWO different objects, but at the beginning of the function execution, they of course are equivalent. – js1568 Aug 27 '12 at 17:19
  • @js1568 Well, yeah, but that's when it's not in the global scope. Most libraries won't be bothering to check their variables like this unless it was in the global scope. You are right, though. – Some Guy Aug 27 '12 at 17:59
3

var something = something || {};

can be used inside of functions with parameters that may not be set

    function doStuff( arg1, arg2, arg3 ) {
        arg2 = arg2 || {};
        arg3 = arg3 || arg1 + 2;
    };

this makes the second and third arguments optional when you call the function doStuff

Decker W Brower
  • 931
  • 6
  • 16
2

This creates a new object with local scope. If the outer something is null, false, or undefined (or otherwise falsy), the new variable will be an empty object {}.

js1568
  • 7,012
  • 2
  • 27
  • 47
  • Not necessarily outer; a redeclaration isn't an error and doesn't overwrite. (Unless you're in strict mode.) – Ry- Aug 27 '12 at 17:22
  • In fact, now that I read it again, this is completely wrong. – Ry- Aug 27 '12 at 17:26
  • I think I have an underlying assumption that this statement is within a function or closure. But I disagree it is completely wrong. For example: jsfiddle.net/3RfYV/1 – js1568 Aug 27 '12 at 17:28
  • http://jsfiddle.net/minitech/QtpKS/ <-- It's wrong. – Ry- Aug 27 '12 at 17:29
  • Erm... your jsFiddle disproves your statement. – Ry- Aug 27 '12 at 17:29
  • Point is, they don't match: http://jsfiddle.net/QtpKS/1/ You didn't change the original value in the outer scope. – js1568 Aug 27 '12 at 17:32
  • 1
    I know, and that isn't my point at all. The outer `something` is ignored because it is redefined as `undefined`. – Ry- Aug 27 '12 at 17:35
2

You're not redefining scope, you're simply ensuring that a variable exists within the existing scope. The assignment statement can be read as:

"If something exists (and is not undefined, null, 0 or false, set something = something (i.e., do nothing). If it doesn't exist, create it and set it equal to an empty object literal"

jackwanders
  • 15,612
  • 3
  • 40
  • 40
  • 1
    @js1568: No. If `something` already exists in the scope, `var something` does not do anything. – Felix Kling Aug 27 '12 at 17:17
  • @FelixKling That is correct in the same scope, you are (possibly) overwriting the same object with the same object. However, we are assuming this is the first line of a function, where this will be in a different scope. – js1568 Aug 27 '12 at 17:24
  • @js1568: Of course variables declared with `var` are local, but nowhere is it stated that we are talking about functions here. Why do you assume that? And Jack explicitly mentioned that it ensures the existence of the variable in the *existing* (I read it as *current*) scope. – Felix Kling Aug 27 '12 at 17:28
  • Fair enough, I understand your point. I over-read there. – js1568 Aug 27 '12 at 17:34
  • I agree with @FelixKling. If `var something = something || {}` were the first line of a **new** scope, then the result will always be `var something = {}`, regardless of whether a variable called `something` exists in an outer scope. – jackwanders Aug 27 '12 at 17:35
2

This construct is pretty useful to not overwrite existing data. Let's assume we're dealing with multiple Javascript files and we want to share some data on some object.

a.js

var share = window.share = share || { };
share.thisIsA = true;

b.js

var share = window.share = share || { };
share.thisIsB = true;

If we have even more than two files and we load those files asyncronously (we can't guarantee order) we don't overwrite that global share object if it was defined and filled before. This is a very common practice for namespacing objects or config objects.

Another very common use case is for creating default values. For instance

function foo( option ) {
    option = option || 'something';

    if( option === 'foobar' ) {} // ...
}

There, we use the patter to have at least one known and defined value for our option argument, if the function gets called with out arguments. You can see that very often in plugin code for instance.

jAndy
  • 231,737
  • 57
  • 305
  • 359
2

It's the same as doing:

var something = ( something ) ? something : {};

Where ( something ) is the evaluation of a truthy or falsy value. If truthy (something exists) it will equal itself, or otherwise an empty object.

David G
  • 94,763
  • 41
  • 167
  • 253
0

Looks more like it's ensuring that something is an object you can hang things on. Setting a default.

Once you call var something or set it as a parameter of the function all instances of something in that scope are the new variable, you can't access the instance in the higher scope.

(function() {
  var something = 'foo';

  (function() {
    var something = something || 'bar';

    console.log(something);
  })();

  console.log(something);
})();

will output

'bar'
'foo'
Tal
  • 1,298
  • 2
  • 10
  • 20
0

The OR constructor in javascript is close to this function

function or(a, b)
{
  if(a) return a;
  else return b;
}

When "a" evaluates to true, it doesn't even check for "b" (nor executes it, but it is not the function case). Moreover, it returns pure "a" without changing it into boolean. The construction of non-boolean variables "ORed" evaluates to the first that turns into boolean true. It is widely used in places, when something can be not supported.

var functionDoingSomethingCrossBrowser = functionOnMsie 
                                      || functionEverywhereElse;

This coupled with {} (new object) operator fills the variable with empty object when your "something" is not available in scope (most probably undefined, which evaluates to false).

Frizi
  • 2,900
  • 1
  • 19
  • 25