So, a few years ago, I was teaching web development at a local coding bootcamp, and a student asked me this question:
I felt like I knew the answer to this question, but when I tried to explain it, I couldn't put it into words. I had a feeling about it, but my actual knowledge was surprisingly hazy.
There's nothing more humbling than teaching 😅. Students have a knack for identifying the "fuzzy spots" in our understanding.
This is especially true for React developers. Most of those JSX rules you've had to memorize, and always forget to follow, are the result of this statement/expression duality.
In this blog post, I'm going to share some of the epiphanies I've had about this distinction, and how we can use this information in our day-to-day work.
Link to this headingExpressions
For example, these are all expressions:
5 * 10→ produces
num > 100→ produces either
isHappy ? "🙂" : "🙁"→ produces an emoji
[1, 2, 3].pop()→ produces the number
Expressions can contain expressions. For example, how many expressions do you count in this chunk of JS code? Make a guess, and then drag the slider to see them each highlighted:
Link to this headingStatements
Here's how I like to think about this: statements are the rigid structure that holds our program together, while expressions fill in the details.
Statements often have "slots" for expressions. We can put any expression we like into those slots.
For example, declaring a variable has an expression slot:
We can use any of the expressions we saw earlier in that slot:
In terms of valid syntax, expressions are interchangeable. If a statement has an expression slot, we can put any expression there, and the code will run. We won't get a syntax error.
That said, we can still run into other issues. For example, the following code is syntactically valid, but we'll crash the browser tab if we try to run it, since it causes an infinite loop:
Link to this headingA handy trick
Want to know whether a chunk of JS is an expression or a statement? Try to log it out!
If it runs, the code is an expression. If you get an error, it's a statement (or, possibly, invalid JS).
As a bonus, we can even see what the expression resolves to, since it'll be printed in the browser console!
This works because all function arguments must be expressions. Expressions produce a value, and that value will be passed into the function. Statements don't produce a value, and so they can't be used as function arguments.
Even as an experienced developer, I rely a ton on
console.log. It's a wonderfully versatile tool!
Link to this headingExpressions as statements
Here is an expression:
1 + 2 + 3.
What happens if we create a JS file that includes only this expression? Let's imagine we save the following content as
How many statements does this file have? Zero or one?
Here's the deal: expressions can't exist on their own. They're always part of a statement. And so in this case, we have a statement that looks like this:
The statement is essentially empty aside from its expression slot. Our expression
1 + 2 + 3 fills this slot, and our statement is complete.
In other words, all of the following lines are valid statements:
Often, tutorials will falsely state that expressions are statements, but this isn't quite right. Expressions and statements are distinct things. But it's possible for a statement to wrap around an expression without providing any additional characters. Think of it like wrapping a sandwich in clear shrink wrap.
Statements typically end in a semi-colon, which marks the end of the statement. The semi-colon isn't necessary for certain statements, like
while loops, and function declarations.
Link to this headingPractical implications in React
If you've worked with React before, you're probably aware that squiggly brackets (
If we try to embed a statement here, like an if/else statement, we'll get an error:
This blows up because statements don't produce a value, only expressions produce a value. If we want to embed if/else logic in our JSX, we need to use a ternary operator expression:
Incidentally, I'm in the process of creating a comprehensive React course, the resource I wish existed when I was learning React. It's called The Joy of React, and you can sign up for updates today!
Link to this headingIn summary
Expressions produce a value, and these values are slotted into statements, like a Super Nintendo cartridge that changes what the Super Nintendo does.
Expressions are always part of a statement, even if that statement is otherwise empty. For example, the code below runs a loop without using a
for statement, but it still includes an “empty wrapper” statement:
It can take a while for this distinction to become intuitive, but hopefully this blog post has clarified a few things!