10

I have downloaded a javascript script and one of the first line is :

 qq = qq || {};

What does it mean?

Patrick Desjardins
  • 136,852
  • 88
  • 292
  • 341
  • 2
    init the object if it is not initialized – Igor Jun 17 '11 at 18:44
  • @Igor There is only one object there, `{}` -- `qq` is just a *variable* (or, if this is in the global context, a *property*) –  Jun 17 '11 at 18:56
  • @Felix Kling: then click "close" and mark it as a duplicate. – Josh Davis Jun 26 '12 at 13:58
  • @JoshDavis: I expect he did, Felix is pretty used to how SO works. The system automatically puts that comment in when you do that. – T.J. Crowder Jun 26 '12 at 14:05
  • @Josh: Yep, these comments are automatically generated. And close votes expire after a while, I voted to close this question a year ago. – Felix Kling Jun 26 '12 at 14:13
  • I didn't notice it was from last year, I thought it was from last week. Explains why I got the first "close" vote. – Josh Davis Jun 26 '12 at 14:32

5 Answers5

23

It checks qq for a pre-existing truthy value or else (||) sets it as an empty object ({}).

In essence, it's purpose is to quickly ensure that any further references to qq will not be undefined, so you can check for properties of the object without your script breaking due to the fact that the variable isn't even a valid object in the first place.

Kzqai
  • 22,588
  • 25
  • 105
  • 137
  • 6
    It checks if it is "falsy" rather than simply whether it is defined or not. This usually works because `undefined` is a falsy value. But if it is defined and it is a falsy value then it will overwrite the existing value. `var qq = false; qq = qq || {}; q // {}` – Cristian Sanchez Jun 17 '11 at 18:56
  • Yep, that is true. Clarified slightly. – Kzqai Jun 17 '11 at 18:58
  • 1
    Note: 0, and empty string are both considered "falsy". – CaffGeek Jun 17 '11 at 19:35
  • 2
    **This doesn't check for "existence of the variable".** If the variable (or global property) is not bound this will *result in exception*. The word "exists" should not appear at all in this answer. Consider starting with "Checks the variables value..." or similar. –  Jun 17 '11 at 20:42
  • Ok, kinda a technical point, I'm just trying to convey the behavior and purpose in plain language, but I've changed the wording some to be more clear, and used the "truthy" word for exactness. – Kzqai Jun 18 '11 at 01:13
  • Your explanation looks pretty good to me. For the OP's edification, I'd just add that a slightly more correct version of this idiom would be something like `if (Object.prototype.toString.call(qq) !== "[object Object]") { qq = {}; }`, because the version `qq = qq || {}` will behave incorrectly if `qq === true` for example. – Domenic Jun 18 '11 at 01:56
  • @Tchalvak I like(d) this answer because it's very succinct. The pedantic/pedagogical sides of me just leak out ;-) –  Jun 18 '11 at 18:44
  • Your answer is good for more info. I was actually trying to look up the "assignment as an expression" idea to explain that, since I think that's the big thing that makes the code less clear. – Kzqai Jun 19 '11 at 23:55
7

In JavaScript the || (logical-or) operator has this logic-table:

A      | B          | A || B
Truthy | Don't care | A   (guaranteed to be Truthy)
Falsy  | Don't care | B   (may be Truthy or Falsy)

(See Truthy and Falsy in JavaScript for what the terms mean.)

Therefor, in the case of qq = qq || {}:

If qq initially evaluates to a Falsy value then the result of qq || {} is {} and thus ({}, a Truthy value) is assigned to qq. Otherwise, qq was initially a Truthy value and the result of qq || {} (which is the result of evaluating qq) is assigned to qq.

This is an idiomatic guard used to easily protect against "undefined" arguments, properties, and similar.

Some people may prefer to use the following near-equivalent construct instead:

if (!qq) {
  qq = {}
}

This latter case, however, will only assign to qq if qq was initially Falsy; the form qq = qq || {} always makes the assignment, but such "overhead" is so trite it should not be used as justification to not use the approach.

Happy coding.

4

Explanation:

    qq = qq || {};
// ^^ is equal to iself, but if it does not exist, 
//       then it is equal to an empty object

For example:

for(var i = 0; i < 5; i++){
    qq = qq || {};
    qq[i] = 'something!';
}

Fiddle: http://jsfiddle.net/maniator/dr5Ra/

Naftali
  • 144,921
  • 39
  • 244
  • 303
3

The answers here so far miss out an important point. The OP says that the script starts with

qq = qq || {};

If so, and if qq hasn't been declared anywhere (no var qq at global scope, no window.qq = ...), that code will throw a ReferenceError. It will not just default qq.

In contrast, if the code were:

var qq = qq || {};

That would be very different indeed. It would do this:

  1. The var qq part would be processed prior to any step-by-step code in the script. If there is already a global qq variable, it will be a no-op. If there isn't, it create a global qq variable with the initial value undefined.

  2. When step-by-step execution reaches that line, the right-hand side of the assignment is evaluated like this:

    • If qq has a "falsey" value (0, "", undefined, false, NaN, or null), the expression qq || {} evalutes to {}.

    • If qq has a "truthy" value (anything not falsey), the expression evalutes to qq.

    (For more details: JavaScript's Curiously-Powerful || Operator.)

  3. The result of the right-hand-side is assigned to qq.

The var makes a big difference.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

qq will receive qq or will be a new object ({}) if it didn't exist.

Kzqai
  • 22,588
  • 25
  • 105
  • 137
Topera
  • 12,223
  • 15
  • 67
  • 104