Josh K
Josh K

Reputation: 28883

JavaScript Object instantiation

Sometimes I'll see code like this:

var Obj = Obj || {};

What does this do? I have had success writing

array = array || [];

To instantiate an array if it hasn't already been instantiated, however I would like to know a bit more about the mechanics of this.

Upvotes: 9

Views: 5653

Answers (4)

Peter Ajtai
Peter Ajtai

Reputation: 57685

The technique tries to make use of something called short circuit evaluation... but it's tricky in Javascript, and turns out to be quite dangerous if you try to make use of it for Object instantiation.

The theory behind short circuit evaluation is that an OR statement is only evaluated up to the first true value. So the second half of an OR statement is not evaluated if the first half is true. This applies to Javascript......

But, the peculiarities of Javascript, in particular how undeclared variables are handled, make this a technique that has to be used with great care to instantiate objects.

The following code creates an empty object except if Obj was previously declared in the same scope:

var Obj = Obj || {}; // Obj will now be {}, unless Obj was previously defined
                     //  in this scope function.... that's not very useful...

This is because after var Obj, Obj will be undefined unless it was declared in the same scope (including being declared as a parameter to the function, if any).... so {} will be evaluated. (Link to an explanation of var provided in the comments by T.J. Crowder).

The following code creates an empty object only if Obj has been previously declared and is now falsy:

Obj = Obj || {};     // Better make sure Obj has been previously declared.

If the above line is used when Obj has not been previously declared, there will be a runtime error, and the script will stop!

For example this Javascript will not evaluate at all:

(function() {
    Obj = Obj || "no Obj"; // error since Obj is undeclared JS cannot read from 
    alert(Obj);​            //   an undeclared variable. (declared variables CAN
})();                      //   be undefined.... for example "var Obj;" creates 
                           //   a declared but undefined variable. JS CAN try
                           //   and read a declared but undefined variable)

jsFiddle example

But this Javascript will always set Obj to "no Obj"!

var Obj ="I'm here!";
(function() {
    var Obj = Obj || "no Obj"; // Obj becomes undefined after "var Obj"...
    alert(Obj);  // Output: "no Obj"
})();​

jsFiddle example

So using this type of short circuit evaluation in Javascript is dangerous, since you can usually only use it in the form

Obj = Obj || {};

Which will fail precisely when you would most want it to work... in the case where Obj is undeclared.


Note: I mention this in the comments of the penultimate example, but it's important to understand the 2 reasons that a variable can be undefined in Javascript.

  1. A variable can be undefined because it was never declared.
  2. A variable can be undefined because it was declared but has not had a value assigned to it.

A variable can be declared using the var keyword. Assigning a value to an undeclared variable creates the variable.

Trying to use an undefined variable that is also undeclared causes a runtime error. Using an undefined variable that has been declared is perfectly legal. This difference is what makes using Obj = Obj || {}; so tricky, since there is no meaningful form of the previous statement if Obj is either undeclared OR it is a previously existing variable.

Upvotes: 11

jhurshman
jhurshman

Reputation: 6067

The key to understanding this syntax is that the result of a boolean or (or and) expression in JavaScript is the last-evaluated component. As has been pointed out by other commenters, JavaScript's shortcircuiting is being used along with this feature to conditionally set the value of array or Obj.

Obj = Obj || {};

This means Obj is set to the value of the expression Obj || {}. If Obj is "true", meaning it evaluates to true (for an object, this means it exists), the result of the expression is Obj, because the expression short-circuits. However, if Obj is "false" (non-existent), the second part of the expression must be evaluated. Therefore, in that case, the value of the expression is {}.

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

var Obj = Obj || {};

I think that the var here is not necessary. It should be:

Obj = Obj || {};

Where Obj is defined elsewhere. This will simply assign Obj to an empty object if it is null or leave as is of not. You might also leave the var keyword in which case it will ensure that the object is declared even if it wasn't before this statement.

Same for the array: if it is null it will assign it to an empty array.

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1074038

The mechanics are a bit unusual: Unlike most languages, JavaScript's || operator does not return true or false. Instead, it returns the first "truthy" value or the right-hand value. So for instance:

alert("a" || "b");              // alerts "a", because non-blank strings are "truthy"
alert(undefined || "b")         // alerts "b", because undefined is falsey
alert(undefined || false || 0); // alerts "0", because while all are falsy, 0 is rightmost

More in this blog post.

As Darin said, your var Obj = Obj || {}; is probably not a literal quote, more likely something like this:

function foo(param) {
    param = param || {};
}

...which means, "if the caller didn't give me something truthy for param, use an object."

Upvotes: 3

Related Questions