3

I'm trying to figure out why you might use the following code:

    var myObject = myObject || {};

I've seen this used several times, but don't understand why this would be necessary. Thanks for your responses.

user699242
  • 1,833
  • 4
  • 21
  • 31

3 Answers3

4

People call JavaScript's binary or || the defaulting operator

var myObject = myObject || function(){};

is the same as

var myObject = myObject ? myObject : function(){};

The following code

var AppSpace = AppSpace || {};

is used because multiple files are going to set and use the namespace, and you don't want to overwrite the namespace if it has already been created. That way, it doesn't matter which file is included first.

Here's another example of defaulting.

function doSomething (callback)  {
   something();
   code();      
   callback = callback || function() {};
   // Now we can call the callback even if it wasn't passed in.
   callback();         
}

However, be careful of the following problem Why does IE nuke window.ABC variables?

That is if a namespace has been defined using

window.AppSpace = {a: 1};

And another file sets

var AppSpace = AppSpace || {}

In IE, it will overwrite the value of window.AppSpace to the empty object if the two scripts are in different script tags because of variable hoisting and the fact that IE doesn't realize that window.a and var a at the top level are all pointing at the same variable.

Community
  • 1
  • 1
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • http://elegantcode.com/2011/01/26/basic-javascript-part-8-namespaces/ This is what I'm wondering about. Why even check, if you want your object to equal your function or the class. – user699242 Sep 14 '12 at 18:24
  • @FabrícioMatté C family? I didn't think so, in C, `||` always returns a boolean. It's usually true in loosely typed languages – Ruan Mendes Sep 14 '12 at 18:25
  • Let me revise it while I compile a C program. `=]` – Fabrício Matté Sep 14 '12 at 18:29
  • 1
    Yes, that pesky C won't support cool things. `:(` I should've worded it *C-derived* languages as JS (broad C family) and PHP (written in C). – Fabrício Matté Sep 14 '12 at 18:35
  • 2
    PHP doesn't do it either. It always returns a boolean. – cHao Sep 14 '12 at 18:36
  • @FabrícioMatté Not your day :) `echo 0 || 'Hello World';` outputs `1` in PHP – Ruan Mendes Sep 14 '12 at 18:37
  • Removed first comment, yes my bad, I always use ternaries in PHP.. I should sleep at night more often. – Fabrício Matté Sep 14 '12 at 18:38
  • In PHP you can use the ternary shorthand to mimic that behavior though - `$foo = $foo ?: 'default';`. Alright time to work a bit more until I start breaking all the PHPs. `=]` – Fabrício Matté Sep 14 '12 at 19:15
  • @FabrícioMatté Sure you can, but it doesn't look nearly as cool, you can do that in any language with casting and void pointers. – Ruan Mendes Sep 14 '12 at 19:17
  • True that. Nothing as hackish yet elegant as that. You can even put expressions inside of it: `var myObject; myObject || (myObject = {});` - even though slightly less readable, theoretically it should have a better performance as it doesn't perform an assignment if the value is already truthy. – Fabrício Matté Sep 14 '12 at 20:50
  • @FabrícioMatté I can't stand premature optimization, specially at the cost of readability, sorry. – Ruan Mendes Oct 16 '12 at 17:25
  • Both ways have the same level of readability for me, of course, that depends on your group's code style guidelines. – Fabrício Matté Oct 16 '12 at 17:27
  • @FabrícioMatté You cannot say that an assignment inside of a boolean expression has the same level of readability as not having one – Ruan Mendes Oct 16 '12 at 17:55
  • The code I write usually comes from [this](http://i.imgur.com/hU1Gn.png) to something [slightly](http://stackoverflow.com/a/12521126/1331430) more complex when it is about JS, assignments and expressions inside control flow statements are a very trivial thing for me (yes I'm different). `=]` – Fabrício Matté Oct 16 '12 at 18:27
  • @FabrícioMatté I'm glad I don't have to read code you write. You should write code for others to read. More than 99% don't like that style (specially a gigantic hard to understand boolean expression). When you do that kind of thing, you're pissing off the next developer. – Ruan Mendes Oct 16 '12 at 20:03
  • I understand your point, that's why I hardly ever contribute to open-source projects (except when I find a bug that needs fixing). Thankfully, in the projects I code for, I'm the one responsible for maintaining the code - and usually there's much worse pieces of code from other parties. But from a neutral view point, I do not use as much bitwise operators and hex numbers instead of decimals as many devs do. – Fabrício Matté Oct 16 '12 at 21:32
2

function(){} is an empty class since classes are functions in JavaScript. This code in particular is taking advantage of the early-exit from OR in JavaScript - it evaluates the first item, and sets the result equal to that if it's truthy and equal to the second item if it's falsy. So if myObject is truthy (not null), myObject equals that, and if it's not then it equals an empty function.

Basically, what this code is saying is "if myObject is already something, leave it where it is, and otherwise make it equal to this blank function".

Andrew Latham
  • 5,982
  • 14
  • 47
  • 87
  • Does this help you, or were you more wondering about the function(){} part on a conceptual level? – Andrew Latham Sep 14 '12 at 18:19
  • Andrew, thanks. I get that, but if the function was filled with properties and methods, why would you want to not overwrite the current myObject if it already exists. What is the benefit of checking if it exists if you want myObject to equal your constructor. – user699242 Sep 14 '12 at 18:21
  • What do you mean, myObject equal to your constructor? If you mean function(){}, that isn't a constructor, it's a blank object. Basically, myObject could be undefined, and we'd rather it be a blank object if that's the case. If it's not null, then we'd like to leave it the way it is. This code would be used in a place where it might be hit more than once, or where myObject might already exist. There are a lot of reasons to set it equal to a blank object instead of undefined - for instance, so that later on you can add methods/properties to it, which would be a problem if it were undefined. – Andrew Latham Sep 14 '12 at 18:24
  • Every function is a constructor, if called with `new` – Ruan Mendes Sep 14 '12 at 18:27
  • If you say var Obj = Obj || {}; Then, go on to define Obj as a constructor of a class or a fucntion. Why check if it exists? Why not just define it the way you want to without the check? – user699242 Sep 14 '12 at 18:28
  • @user699242 See my answer for the explanation – Ruan Mendes Sep 14 '12 at 18:33
  • Given the edit made to the question, Juan Mendes' answer is better and I think he explains it pretty well. – Andrew Latham Sep 14 '12 at 18:33
0

This technique is called "Short-circuit" evaluation.

hort-circuit evaluation, minimal evaluation, or McCarthy evaluation denotes the semantics of some Boolean operators in some programming languages in which the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression: when the first argument of the AND function evaluates to false, the overall value must be false; and when the first argument of the OR function evaluates to true, the overall value must be true

http://en.wikipedia.org/wiki/Short-circuit_evaluation

r3joe
  • 46
  • 1