When JavaScript expressions are evaluated, they produce a single value.
3 * 10
// <- 30
If we want to add a condition in an expression, we need to use ternary expressions or logical operators. The following example displays both alternatives, although the former is usually preferred.
[1, -1, -0.5].map(x => x > 0 ? x * 10 : -x * 10)
// <- [10, 10, 5]
[1, -1, -0.5].map(x => x > 0 && x * 10 || -x * 10)
// <- [10, 10, 5]
It can be confusing to create side effects, but you can achieve that through use of commas.
sideEffect(), 3 * 10
// <- 30
It’s not possible to declare variables you might need for temporary storage within an expression. As such, you typically extract these variables into the enclosing scope. More often than not, that’s better for readability anyways, so it doesn’t have a hugely negative impact.
Using do
The do
expression proposal lets you write a block of statements to be evaluated. The “completion value” is returned as the result of a do
expression. In the following example, there’s just a 3 * 10
expression in our block, so that’s our completion value, and 30
is returned.
do { 3 * 10 } // just an expression
// <- 30
The following bit of code is equivalent to the two .map
examples we saw earlier. In this case, we use a do
expression, allowing us to use if
and else
instead of ternary or logical operators.
[1, -1, -0.5].map(x => do { if (x > 0) { x * 10 } else { -x * 10 } })
// <- [10, 10, 5]
Side effects in do
expressions become easier to read, and we are able to declare variables. In the following example we’re purposely missing a return
statement, as do
expressions already implicitly return, as we saw in the case of the if
/ else
example. Naturally, const
and let
variables declared inside a do
block are scoped to that block, while var
variables are scoped to the containing function.
var data = do {
const data = pullSomeData()
doSomethingElse() // sideEffect
data
}
Using do
Today
It’s easy, there’s a Babel plugin we can use.
npm install --save-dev babel-plugin-syntax-do-expressions
Then add the following to your .babelrc
file or the babel
property in package.json
.
{
"plugins": ["syntax-do-expressions"]
}
That’s it.
Whenever you run the Babel CLI, it’ll understand do
expressions.
Conditionals in JSX
A while back I wrote about “the weird parts” of using JSX – the JavaScript syntax extension Facebook built to help you write templates for React apps. Back then, I mentioned how sometimes you have to write code like the following when you want to conditionally render a piece of markup.
return (
<nav>
<Home />
{ loggedIn && <LogoutButton /> || <LoginButton /> }
</nav>
);
With do
expressions, you could get rid of the weird-looking and oft-confusing logical operators. This makes the code easier to read and saves you from having to deal with falsy expressions like 0
or ''
.
return (
<nav>
<Home />
{
do {
if (loggedIn) {
<LogoutButton />
} else {
<LoginButton />
}
}
}
</nav>
)
When there’s larger pieces of markup it becomes more elegant to be able to use statements instead of expressions – and do
let’s you do
that. The do
syntax makes it easier to read conditionals, allows you to use variables, and makes it clear when part of an expression is a side effect.
Comments