views:

76

answers:

7

Hi Everyone,

Setting default values is one of my favourite things to do when creating JavaScript applications. While working, i came across a bug that could have easily escaped me.

This is how the object is used.

var obj = new App({
             imgs: [];
             preload: false
          });

This is how the object is defined.

var App = function(o) {

    this.imageFolder = o.imgs;

    this.preload = o.preload || true; // the idea is to set a default value of true

    if(this.preload) {

     // preload images here    

   }

}

My question is, how do you handle boolean values when using the || operator

+4  A: 
this.preload = "preload" in o ? o.preload : true;
bkail
+1 also correct
Q_the_dreadlocked_ninja
+1  A: 

|| stands for or. Let's look at some sample values:

this.preload = o.preload || true;

If o.preLoad = true:

true || true is the same as  = true;

If o.preLoad = false:

false || true always will equal true

Since you define o.preLoad as having a default value of false, the statement will always evaluate to true.

Tom Gullen
+1  A: 

My question is, how do you handle boolean values when using the || operator?

Mine is not an exhaustive answer. @bkail's solution should do the trick. However, I would like to point out the following:

The || operator produces the value of its first operand if the first operand is truthy. Otherwise it produces the value of the second operand1.

var preload;                     // undefined is falsy
preload = preload || true;
console.log(preload);            // true

var preload = false;             // false is obviously falsy
preload = preload || true;
console.log(preload);            // true

var preload = "";                // empty string is falsy
preload = preload || true;
console.log(preload);            // true

var preload = null;              // null is falsy
preload = preload || true;
console.log(preload);            // true

var preload = "something else";  // a non-empty string is truthy 
preload = preload || true;
console.log(preload);            // returns "something else", the first operand

var preload = {};                // even an empty object is truthy
preload = preload || true;
console.log(preload);            // returns "Object {}"

1 Source: JavaScript: The Good Parts by Douglas Crockford - Page 17

Daniel Vassallo
+2  A: 

I don't think that construct is appropriate when assigning boolean values (I'd also be careful doing this with numbers) for just the reason you've given- a false value will be considered invalid, even though it's fine and indeed desired.

in your case you could do the assignment with

this.preload = o.preload && true;
lincolnk
+1 for simplicity
Q_the_dreadlocked_ninja
@Q_the_novice, This returns undefined if `o.preload` wasn't set. `var o = {};alert(o.preload `
Chad
Ivo Wetzel
Or `o.preload === false ? false : true` as I mentioned in my answer
Chad
@Chad +1 Thanks for pointing that out, did not spent enough time testing.
Q_the_dreadlocked_ninja
A: 

try this:

 this.preload = !o || o.preload == null ? true : o.preload;
Zafer
A: 

This should work

this.preload = o.preload === false ? false : true;

If o.preload IS false, then we set it to false, otherwise, it's true

You just might want to add a o = o || {}; at the start to ensure o exists

Chad
A: 

Just typecast it:

this.preload = Boolean(this.preload);

Or if you don't want non boolean values evaluating to true:

this.preload = typeof this.preload === 'boolean' ? this.preload : false;
balupton