头图

foreword

What is the difference between a statement and an expression in JavaScript?

I seem to know the answer to this question, but when I try to explain it to others, I'm at a loss for words. I have a feeling about this question, but can't articulate it clearly.

I realized later that this question is extremely important. It's arguably the load-bearing wall of the house and will help support a lot of JavaScript knowledge.

Even more so for React developers. Most of those JSX rules you have to remember, and those you always forget to follow, are mostly the result of statement/expression duality.

In this article, I'll share some of my insights on the difference between the two and how we can use this information in our daily work.

expression

Essentially, an expression is a piece of JavaScript code that produces a value.

All of the following examples are expressions:

  • 1 → yields the value 1
  • "hello" → yields the value "hello"
  • 5 * 10 → yields the value 50
  • num > 100 → yields the value true or false
  • isHappy ? "🙂" : "🙁" → the resulting value is an emoji
  • [1, 2, 3].pop() → yields the value 3

Expressions can contain other expressions. For example, how many expressions do you think there are in the JS code below?

 (5 + 1) * 2

The answer is that there are 5 expressions in total.

Specifically, they are the following five:

  1. (5 + 1) * 2 , this code itself is an expression, the resulting value is 12
  2. (5 + 1) , because of the parentheses, this subexpression is evaluated first and resolves to 6 .
  3. 5 , individual numbers are expressions in themselves, because they produce a value. This expression resolves to 5 .
  4. 1 , for the same reason, this expression resolves to 1 .
  5. 2 , this number forms the final expression, which resolves to 2 .

statement

A JavaScript program is a series of statements. Each statement is an instruction to the computer to do something.

Here is an example of a statement in JavaScript:

 let hi = 5;
 if (hi > 10) {
  // 更多语句
}
 throw new Error('报错了');

Here's what I think about statements and expressions: Statements are the rigid structures that underpin our programs, and expressions fill in the details.

Statements often have "slots" for expressions. We can put any expression we like into these slots.

For example, declaring a variable with an expression slot would do:

 let hi = /* 表达式 */;

In this slot, we can use any of the expressions we've seen before:

 let hi = 1;
let hi = "hello";
let hi = 5 * 10;
let hi = num > 100;
let hi = isHappy ? "🙂" : "🙁";
let hi = [1, 2, 3].pop();

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. And we don't get syntax errors.

That said, we may encounter other problems. For example, the following code is syntactically valid, but will crash the browser if we try to run it because it causes an infinite loop:

 while ("hello") {
    // 因为"hello"永不改变,因此循环会一遍又一遍的重复,直到脚本崩溃。
    // 语法上是有效的,但仍是有问题的。
}

Handy Tips

Want to know whether a piece of JS code is a statement or an expression? Try printing it out!

 console.log(/* 这里是JS代码 */);

If it works, the code is an expression. If an error is reported, it is a statement (of course, it may also be illegal JS).

Additionally, we can even see the result of the expression, as the result is printed to the browser's console.

This works because the arguments to any function must be expressions. An expression yields a value, and that value is passed into the function. The syntax does not produce a value, so statements cannot be used as arguments to functions.

Even as an experienced developer, I rely heavily on console.log . It's really a good thing.

expressions as statements

This is an expression: 1 + 2 + 3 .

What happens if we create a JS file that only includes this expression? Let's imagine saving the following as test.js :

 1 + 2 + 3

How many statements are in this file? 0 or 1?

Here's the thing: expressions cannot stand alone. They are always part of a statement. So in this case we have a statement that looks like this:

 /* 表达式插槽 */

Except for the expression slot, the statement is basically empty. The expression 1 + 2 + 3 fills the slot and the statement is generated.

In other words, all of the following lines are valid statements:

 // 语句 1:
let hi = /* 表达式插槽 */;
// 语句 2:
return /* 表达式插槽 */;
// 语句 3:
if (/* 表达式插槽 */) { }
// 语句 4:
/* 表达式插槽 */

Often, some tutorials will incorrectly state that expressions are statements, but this is not entirely true. Expressions and statements are different things. But it is possible for a statement to wrap an expression without providing any extra characters. It's like wrapping a sandwich in clear plastic wrap.

Statements usually end with a semicolon, which marks the end of the statement. Semicolons are not necessary for some statements, such as if statement, while loop and function declaration.

Practice in React

If you've used React, you probably know that curly braces { and } allow us to embed some JavaScript in JSX, like this:

 function CountdownClock({ secondsRemaining }) {
  return (
    <div>
      Time left:
      {Math.round(secondsRemaining / 60)} minutes!
    </div>
  );
}

This is the magic of React, it allows us to have the full power of JavaScript.

But there's a catch - we can't put arbitrary JavaScript code inside curly braces. Specifically, we can only include expressions, not statements. The curly braces essentially create an expression slot in our JSX.

If we try to embed a statement inside curly braces, say if/else statement, we get the error:

 function CountdownClock({ secondsRemaining }) {
  return (
    // 🚫 语法报错
    <div>
      {if (secondsRemaining > 0) {
        `${secondsRemaining} seconds left`
      } else {
        "Time expired!"
      }}
    </div>
  );
}

This is because statements do not produce values, only expressions do. If we want to embed if/else logic in JSX, we need to use a ternary operator expression:

 function CountdownClock({ secondsRemaining }) {
  return (
    // ✅ 没问题
    <div>
      {secondsRemaining > 0
        ? `${secondsRemaining} seconds left`
        : "Time expired!"
      }
    </div>
  );
}

This seems like a weird JSX/React limitation, but it's actually a JavaScript limitation.

I think we often blame React for seemingly arbitrary rules like components must return a top-level element. But more often than not, React is just warning us about a JavaScript limitation.

It is very important to understand the difference between statements and expressions. We also need to understand how JSX is compiled to JavaScript, and how React's scheduling and rendering cycles work... but those topics are beyond the scope of this article.

Summarize

A JavaScript program consists of a series of statements. Each statement is an instruction to do something, say, create a variable, run a if/else conditional statement, or start a loop.

Expressions produce a value, which is put into the statement's slot. An expression is always part of a statement, even if the statement is empty. For example, the following code runs a loop without using the for statement, but it still contains a "clear plastic wrap" statement:

 data.forEach(item => console.log(item));

It may take a while for this distinction to become apparent, and I hope this article helps you.

The above is all the content of this article, welcome to like, collect and forward~


chuck
300 声望41 粉丝