const isThisOrThat = "that" === ("this" || "that") // this is false
Why doesn't this work? Let's talk about it!
Inside the parens
If we go by order of operations, the inside expression evaluates first.
I'll be honest, this one breaks my math brain a bit. In math,
Let's look at two examples.
const example = "" || "that" // "that"
This happens even if the second value is also falsey.
const example = "" || "" // ""
So what happens if the first value is truthy, as in our original example?
const example = "this" || "that" // "this"
example evaluates to
Now we start to realize why our expression up top doesn't work. We can break it into two pieces.
const example = "this" || "that" const isThisOrThat = "that" === example // false
At the time that we're checking equality, the string
"that" is nowhere to be found.
What makes this strange is that order matters.
const example = "that" || "this" const isThisOrThat = "that" === example // true
Flipping the original or expression changes the resulting equality check.
Making sure this works
If we truly want to check both strings, we need to check equality twice.
const isThisOrThat = "that" === "this" || "that" === "that" // true
Alternatively, we can use an array check. This one feels a bit more natural.
const isThisOrThat = ["that", "this"].includes("that") // true
Or is weird
People use or a lot to flip values or set defaults, etc. It's never been my favorite because of examples like the ones above. Once you start composing that expression it can confuse the issue.
Top comments (10)
Yeah, at first it can be confusing. Just one more point to add - In case of
||it behaves as a short circuit. So if you use expressions and your first expression becomes truthy, other expressions will never be evaluated. If there is a function call, it will not execute.
Ah, but it doesn't return a boolean. It returns the value. So yes, the operation logic is reasonable, but the return structure breaks the concept. It's no longer commutative at that point.
Thanks for the write-up!
There are two finer points of the language that may be confusing sometimes even to experienced developers.
The first one is type coercion, which is an automatism to align values for the task at hand. For example, a logical operator will coerce any value to a boolean for the sake of evaluation. An empty string is falsy, a string containing characters isn't. There's quite a complex set of rules to this, and it makes the language easily confusing.
That brings us to the second one, which is operator precedence. I'll spare you the details, it's just that some operators are processed prior to other ones.
No question. And that’s the former is what most of this post focuses on. It resolves each side of the operator to a Boolean and operates accordingly.
Appreciate the effort though, very interesting write up! Keep it up!
Great js quirk analysis Laurie.
Thanks to eslint, this would never get checked in.
As Yoda would say....
Confuzzled, I made you;
Amuse me, this does.