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 = {});
}
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With