airbnb / javascript

JavaScript Style Guide
MIT License
145.56k stars 26.55k forks source link

The use of || operator in assignments #990

Open felipethome opened 8 years ago

felipethome commented 8 years ago

In the topic 15.7 this kind of assignment is favored over ternaries: const foo = a || b;. Actually, this pattern is used in a lot of the examples, but should it be discouraged since it can produce undesired behavior when the left operand is falsy? In the above example if a is falsy so b would be the result.

I know the developer should distinguish problematic cases, but one of the goals of the style guide is to avoid potential issues.

ljharb commented 8 years ago

In the comparison, a || b is always strictly better than a ? a : b, since both have the same hazards.

In the general case, || fallbacks should be rarely necessary, since you can provide default values for those arguments.

felipethome commented 8 years ago

True, but the ternaries has the advantage of the comparison right? So you could do a !== undefined ? a : b

ljharb commented 8 years ago

Sure, but that's not what 15.7 is addressing. In that case, it'd be fine to use a ternary.

felipethome commented 8 years ago

Got you. So, I just created the issue because I already faced one or two bugs because of this pattern of using a || b, but with default parameters like you said we can avoid this kind of problem most of the times. But don't you think this kind of pattern should be discouraged? (not talking about 15.7 anymore, just asking your opinion).

ljharb commented 8 years ago

Yes, if you want to add a new section that in general discourages using || fallbacks in favor of default arguments, I'd be happy to add that.

felipethome commented 8 years ago

Actually, it seems 7.7 already explains that in the comments of the example. Maybe the content of the comment presented as a Why? quote would be more effective?

getify commented 8 years ago

Just FYI: technically the a || b and a ? a : b are not strictly equivalent (but very close). When the a expression is something more than an identifier (an object prop access, a function, etc), if evaluating that expression has side effects, the outcomes will be different in the two cases. a || b evaluates a only once, and a ? a : b evaluates a twice.

ljharb commented 8 years ago

That is true - and even more of a reason why a || b is a better pattern.