When you retrieve an object value thatโs undefined
, it will crash due to a TypeError! So make sure you do an initial check with an if
statement. Better yet, refactor this using &&
๐
Using &&
in this way is sometimes called the Guard Operator because the 1st expression safeguards the 2nd expression. In other words, only if the 1st expression is truthy, then will the 2nd expression be evaluated.
const forest = {}
forest.tree // undefined
forest.tree.seed // TypeError ๐ฑ
// This will prevent the TypeError but...
if(forest.tree) {
forest.tree.seed
}
// โ
Much better using &&
forest.tree && forest.tree.seed // undefined
Understanding the && Operator
I always thought the &&
was just used for boolean checks like this:
if(a && b) {
// do something
}
I never thought you can use &&
to evaluate to something or produce some sort of value. So when I first learned of this Guard Operator, I was super confused. So don't worry if you are too. It will take some time to understand this. The resource that helped me finally understand this is Kyle Simpson's "You Don't Know JavaScript" book.
How he describes it is think of &&
not just as logical operator but Selector Operators. They don't result in a boolean value or logic value. Instead, the result is always one of the two expressions. In his words, they select one of the 2 operands' values.
The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions.
Before you throw in the towel, let's take a look at an example:
const truthy = true;
const falsy = false;
const money = '๐ฐ';
truthy && money; // '๐ฐ'
falsy && money; // false
So money
will be selected if the 1st expression (left side) is truthy. Otherwise, the 1st expression will be selected and the 2nd expression (right side) won't be evaluated. This is what's called Short-circuit evaluation because the 2nd expression is never evaluated.
And here's the definition from Kyle Simpson's "You Don't Know JS" book:
The right-hand operand will not be evaluated if the left-hand operand is sufficient to determine the outcome of the operation. Hence, the name "short circuited" (in that if possible, it will take an early shortcut out).
Truthy Value
So essentially the 1st expression (left side) is your truth checker. If it's true, then your 2nd expression (right side) will be selected. If your 1st expression is false, then the 1st expression's value will be used. In order to understand what's truthy, let's go over it ๐ค
The truthy value list is quite an extensive one. So instead of remembering what's truthy. It's a lot easier to just remember the falsy list. And whatever is not on falsty list, is considered truthy ๐ (I wrote another blog post on Falsy Values, which you can read it here)
// JS Essentials: Falsy Values
false
undefined
null
NaN
0 or +0 or -0
"" or '' or `` (empty string)
// Everything else is truthy
Refactoring if
conditionals with &&
Let's look at another example to see how the guard operator can also be useful to refactor conditional statements.
const steak = '๐ฅฉ'
function cook() = {...}
// Most people use `if`
if(steak) {
cook()
}
// Refactored using &&
steak && cook(); // `cook` only gets called if `steak` is true
Here's a good one to think about this:
someCondition && doSomething()
Thanks: @marcdel
Proposal Optional Chaining
So this is really exciting. The EcmaScript folks or the JavaScript committee is proposing an "Optional Chaining" syntax. When I was working in C#, this was such a game changer for me. I always wished JavaScript would have something similar. Really hope this proposal goes through ๐
Rewriting our example with the Proposed Optional Chaining Syntax ๐คฉ:
// Current
forest.tree && forest.tree.seed
// Proposal
forest.tree?.seed
DO NOT use this in your app, this is currently NOT supported.
Read more about the proposal here.
Resources
- MDN: Logical operators
- YDKJS: Types & Grammer
- YDKJS: Short Circuited
- Guard And Default Operators In Javascript
- JavaScript/Operators
- SamanthaMing.com: Falsy Values
Thanks for reading โค
Say Hello! Instagram | Twitter | Facebook | Medium | Blog
Top comments (18)
This is something you see a lot when stringing shell commands together.
This way of using
&&
before running a function (or command) and calling it a "guard operator" makes it seem like it's not what it actually is (an expression).It gets a little odd when you try to do things that seem to make sense on the face of it, like use an assignment instead of a final expression:
And it can be tempting to string too many of them together and make quite a confusing line.
I prefer to be explicit, and to dive out if the condition isn't met:
Maybe 'Gate' would be a better word?
Why would one prefer the
&&
operator over a conditional? At first glance, the later seems 'better' in many ways:if (x.y !== undefined)
x.y &&
will result in undefined ifx.y
isundefined
, rather than entering anelse
clauseIt's a one-liner, sure, but I would argue ternary operators are a better fit:
x.y ? f(y) : g()
over(x.y && f(y)) || g()
.Not saying you're wrong, but I'm curious about the reasoning.
I'm in agreement with those opposing this idiom. The Javascript phrase:
obj && obj.prop && obj.prop.send();
is an expression, and (to me at least) should be pure, like a pure function. As used above, this expression is used only for its side effect. I would always prefer to be explicit. I like the proposed optional chaining; but until that's available, write this statement in English:
// pedantic
if (obj && obj.prop && typeof obj.prop.send === 'function') {
obj.prop.send();
}
Thatโs the really interesting thing about JS or programming in general. There are always multiple ways of solving things. Some of them are definitely a syntactic choice. Iโm always in the camp of expanding my toolkit so when I run across it (especially from others code), I know whatโs going on. But at the end of the day, youโre the owner of your code, so pick the way that makes the most sense to you ๐
You could use OR defaulting to protect against Type Errors, too:
Or take this a step further and write a helper for this:
(iterative version)
(recursive version)
I typically use the โ||โ for setting the default values. Thanks for sharing your solution ๐
Is it just me, or does it feel like the elvis operator will only enable us to be more negligent?
Nothing stops us writing
when what we really needed was
Which will make the code not "fail fast", even though there's no correct logic when the
a
has nob
or a presentc
has nod
.The currently possible code:
tells us a lot more about the structure. And it's not a token longer!
The main problem here is that a 3-level destructuring is seen as "showing off" most of the time, and (often correctly) shamed as "unreadable", here one can just say this is "defensive programming". Which it's not, since you are failing to throw valuable errors in the "safe" inner code.
So, I am sure there are genuine uses, I have many places in my code I'd like to use it myself, especially the
?.()
. But I fear it will be overused, and its overuse "well-justified".Youโre absolutely right! Itโs one of those common JS saying, just because you can doesnโt mean you should. When itโs used appropriately, itโs super helpful. And if you abuse it, it becomes a code smell. Definitely something to be careful of. Thanks for pointing that out ๐
That spicy proposal looks exciting. 'Elvis' operator is totally suited to javascript
Hahaha, I think I learned something new! Never knew that was called the โelvisโ operator ๐
I first heard it referred to as that when I was reading through a groovy scripting tutorial!
The Elvis operator
?:
returns left-hand side if it is trueish, right-hand side otherwise, thus comparable toobject || default
. groovy-lang.org/operators.html#_el...It is called Elvis because it looks like an Elvis emoticon, but I always memoized it with "Not sure if he still exists" :-)
OTOH, the safe-navigation operator
?.
will return left-hand side if it is null, otherwise evaluate right-hand side on the result of left-hand side, thus comparable toobject && object.prop
groovy-lang.org/operators.html#_sa...So the proposal for JavaScript is not the Elvis operator, but comparable to the safe-navigation operator.
Indeed! Yes, thanks for the correction. In my new blog post, I talk about the Elvis Operator and hopefully others won't make the same confusion as I had ๐
The issue comes when people chain up 5 at once and you get bogged down with the 4 or so properties before the one you're trying to get.
Much prefer lodashes
has
or object destructuring.I always felt using the && operator in this manner was an unintentional. And that its a quirk of JS. Like it should only be used in the if statement. Nevertheless it's super useful.
Definitely something to keep in your toolkit. Even if you donโt use it. If you ever come across that code, at least you will be able to follow what other people are trying to do ๐
Should recommend github.com/facebookincubator/idx