Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between `var options = options || {}` and `options || (options = {})`

Tags:

javascript

I often use var options = options || {} as way to default to an empty object. It's often used to initialize an option object in case it's not passed in the parameter of a function call.

The thing is I've read in several places (blog posts, source code) that options || (options = {}) better express the developer's intent. Can someone elaborate on it? I don't see the functional difference between the two, so there's something I must be missing here.

--- edit

I saw in Backbone.js source code in several places, like https://github.com/documentcloud/backbone/blob/0.9.2/backbone.js#L273

I think I saw it too in jQuery's source code too. And in the multiple Js writing style guides that flourished.

--- edit 2 code example :

var func = function(param, options) {
   // How I do it
   var options = options || {};
   // How I should do it in the "same" way
   options = options || {};
   // The "other" way
   options || (options = {});

}
like image 258
DjebbZ Avatar asked Nov 19 '12 12:11

DjebbZ


4 Answers

There's no real difference, assuming you meant:

function fn(options) {
    // type a
    options = options || {};

    // type b
    options || (options = {});
}

Mostly a matter of preference, I think (a) is a whole lot clearer, I don't like the statement with no assignment on the LHS.

like image 165
Evan Trimboli Avatar answered Nov 14 '22 17:11

Evan Trimboli


There isn't a functional difference.

The second construct just (subjectively) looks like it does what it does more than the first construct.

The counter argument is that the first construct is a common pattern, so is more easily recognised to do what it does.

like image 45
Quentin Avatar answered Nov 14 '22 18:11

Quentin


They should do the same thing, but there is a better way.

Theoretically the second, assigning only if the value is falsy, could eliminate an assignment and be faster. Indeed in a jsperf we see it is (12%).

In fact the explicit if statement is just as fast as the condition-then-assign:

if(!options)
    options = {};

Try the test on your browser/machine.

I think the explicit if is the most clear, and has no penalty.

Edit:

If you are expecting an object to be passed in to a function, then I think the better test is:

if(typeof options !== 'object') 
    options = {};

This will ensure that you have an object afterwards, even if it is empty. Any other test (for undefined, or falsiness) will permit a truthy non-object through like a non-zero number or a non-empty string. As the jsperf shows, however, this is ~15% slower. Since you only do this on entry to a function which will be processing objects, I would argue that is a worthwhile tradeoff, and is barely slower that the always-assign.

like image 3
Phil H Avatar answered Nov 14 '22 18:11

Phil H


There is a functional difference: one uses var and the other does not. If there is any possibility that the options variable does not exist in the current scope, it is much better to use var rather than risk options leaking out into outer scopes implicitly.

If options is guaranteed to exist (for example, within a function whose parameters include options), the two statements are functionally identical so the problem reduces to the relative stylistic merits of options = options || {} versus options || (options = {}). Personally I see little difference: both require the same knowledge of how JavaScript's || operator works, so once you remove that factor from the equation, I would probably favour options = options || {} as being slightly more readable by virtue of being shorter and simpler. The developer's intention seems equally clear to me in either case.

like image 2
Tim Down Avatar answered Nov 14 '22 18:11

Tim Down