39

I have been doing some reading lately one article I read was from Opera.

http://dev.opera.com/articles/view/javascript-best-practices/

In that article they write this:

Another common situation in JavaScript is providing a preset value for a variable if it is not defined, like so:

if(v){
  var x = v;
} else {
  var x = 10;
}

The shortcut notation for this is the double pipe character:

var x = v || 10;

For some reason, I can't get this to work for me. Is it really possible to check to see if v is defined, if not x = 10?

--Thanks. Bryan

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
bryan sammon
  • 7,161
  • 15
  • 38
  • 48

6 Answers6

71

That Opera article gives a poor description of what is happening.

While it is true that x will get the value of 10 if v is undefined. It is also true that x will be 10 if v has any "falsey" value.

The "falsey" values in javascript are:

  • 0
  • null
  • undefined
  • NaN
  • "" (empty string)
  • false

So you can see that there are many cases in which x will be set to 10 besides just undefined.

Here's some documentation detailing the logical operators. (This one is the "logical OR".) It gives several examples of its usage for such an assignment.

Quick example: http://jsfiddle.net/V76W6/

var v = 0;

var x = v || 10;

alert( x ); // alerts 10

Assign v any of the falsey values that I indicated above, and you'll get the same result.

user113716
  • 318,772
  • 63
  • 451
  • 440
  • Thanks for this answer, so you think it would be best to do: var v = false; var x = v || 10; alert(x) ? – bryan sammon Jan 02 '11 at 03:21
  • 2
    Another way to describe what's effected is: http://jsfiddle.net/robertpitt/V76W6/1/ – RobertPitt Jan 02 '11 at 03:23
  • @bryan: There's no need to assign `false` to `v`. If you simply do `var v;`, it will automatically have an initial value of `undefined`, so if `v` gets some other non-falsey value, `x` will be assigned that value. But if `v` isn't assigned anything, or gets another falsey value, `x` will get `10`. Keep in mind that `0` is falsey. You should only use the "logical OR" in this manner if you're absolutely certain that you don't want `x` to have *any* falsey value. – user113716 Jan 02 '11 at 03:25
  • @RobertPitt: Interesting approach. Sort of lays it all out there at once. Nice. – user113716 Jan 02 '11 at 03:28
  • One more Q, how come when I assign a value to var a on this: http://jsfiddle.net/bryansammon/V76W6/2/ - I still get the alert of 10? – bryan sammon Jan 02 '11 at 03:40
  • @bryan: Because you're assigning it *after* `x` has already been assigned. When `x` is assigned, `a` is still `NaN`. You need to move the `a = "5";` line *above* the line that assigns a value to `x`. [Example](http://jsfiddle.net/V76W6/3/) – user113716 Jan 02 '11 at 03:52
  • Great jsFiddle! I made an objectified version, demonstrating another pitfall: http://jsfiddle.net/V76W6/28/ – chadoh May 30 '13 at 20:40
13
var x = v || 10;

That operator (the "logical" or "short-circuit" OR operator) would normally check the value of v, and if it is a "falsy" value (i.e. it would fail as a condition used in an if statement), 10 becomes the value of x, otherwise v does (and if 10 were a function, it would never be executed).

undefined, null, and 0 are all examples of falsy values that a variable can hold (yes, even the first one), and the operator (or if statement) acts accordingly. In contrast, all objects and arrays (not including null) are "truthy" values, which allows for such things as this (used in the Google Analytics tracker code):

var _gaq = _gaq || []; // Makes a new array _gaq if it is not already there

However, if the referenced variable is not even declared anywhere within the scope chain, then a JavaScript exception will occur.

One way to avoid this is by declaring all your global variables from the start:

var iAmAGlobalVariable;  // Holds the value undefined by default

If this is not possible, you should use the typeof operator. It does not attempt to evaluate its operand, and thus an exception will not occur:

var x;
if(typeof v != 'undefined' && v) {
    x = v;
} else {
    x = 10;
}

Or even better, if you know that the variable would be a global variable, you can treat it as a property of the global (window) object:

var x = window.v || 10;
PleaseStand
  • 31,641
  • 6
  • 68
  • 95
6

If v evaluates to false (for example, 0, null, false) then it won't work. You can manually check for undefined:

var x = v !== undefined ? v : 10;
Thai
  • 10,746
  • 2
  • 45
  • 57
2

I would use triple equals with ternary in a function for this.

function myTest(x){
 return x === undefined ? true: false;
}    

Only returns true if x is undefined

See (http://www.impressivewebs.com/why-use-triple-equals-javascipt/) and (http://jsfiddle.net/V76W6/)

1

I would just use a try-catch

var x = 0;

try
{
    x = v;
}
catch(err)
{
    x = 10;
}
Franz Payer
  • 4,069
  • 15
  • 53
  • 77
0

Here is how to get it working:

var v;         //declare v as undefined
//  v = 5;     //if uncommented x will be 5   

var x = v || 10;
alert(x);      //output: 10

http://jsfiddle.net/uLLtu/1/

Eric Fortis
  • 16,372
  • 6
  • 41
  • 62
  • 1
    Just for the benefit of the few holdouts who still don't see "javascript" and think "jquery", `$(function() { ... });` is what Eric is referring to as "document ready stuff"; it's jQuery's shorthand for `$(document).ready(function() { ... });`, which is (generally) called when the DOM is finished loading (but before the `load` event on `window`). I'm not sure why it's included in this answer in the first place. – eyelidlessness Jan 02 '11 at 03:46
  • @eyelidlessness Thanks for the clarification, you're right there's no need for it, I just forgot to delete them, I was first using markup to illustrate the var content instead of the alert. – Eric Fortis Jan 02 '11 at 04:23
  • I went ahead and removed that portion of your comment. If you would rather I didn't, feel free to rollback. – eyelidlessness Jan 02 '11 at 08:15