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 .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 = {});
}
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 = {});
}
Share
Improve this question
edited Dec 22, 2014 at 19:33
Usman Ismail
18.7k14 gold badges86 silver badges165 bronze badges
asked Nov 19, 2012 at 12:10
DjebbZDjebbZ
1,6041 gold badge20 silver badges34 bronze badges
8
|
Show 3 more comments
7 Answers
Reset to default 5There'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.
There is indeed no functional difference between the two, even though their mechanics are not identical.
The first form sets the local variable options
to be equal to the parameter options
or to an empty object if the argument has a falsy value (e.g. if it has not been provided).
The second form evaluates to the value of the parameter options
(if it's not falsy), otherwise it evaluates to the result of the assignment of the empty object to that parameter. So the difference from the first form is that if options
is truthy, no assignment is performed.
Personally I consider the second form to be a less readable version of
if(!options) {
options = {};
}
to which is identical in both function and mechanics.
There is no functional difference, the idea is that options || (options = {});
is closer to what the programmer really want to express, which is actually:
if (typeof options == "undefined") {
options = {};
}
The ||
operator is used to make shorter code, not clearer code.
Definitely subjective, but I wouldn't use the second.
Reason: I feel that assignments in expressions anywhere deeper than the top-level = obfuscation.
Some C programmers like that (I used to, once), they do things like extra parens to make the assignment more clear... by making the whole expression look unfamiliar. Why bother if you can just be straightforward?
The most clear would probably be:
if (!options) options = {};
options = options || {}
, without re-declaring the variable withvar
. Pity there's no||=
in Javascript – Kos Commented Nov 19, 2012 at 12:14var
is useless in this case. Coffeescript has something for||=
, but it's another story. – DjebbZ Commented Nov 19, 2012 at 13:00