Lesson notes

An expression is any valid unit of code that resolves to a value (source).

Below 5 is an expression, it resolves to value 5:

const x = 5;

Below getAnswer() — a function call — is another expression. This call will return a value, i.e. this function call will resolve to a value:

const y = getAnswer();

Below is an example of an expression that consists of multiple subexpressions, and the step-by-step process of resolving each expression in order until the whole expression is resolved to a single value:

12 + square(7 + 5) + square(square(2));

12 + square(12) + square(square(2));
12 + 144 + square(square(2));
12 + 144 + square(4);
12 + 144 + 16;
156 + 16;
172;

JavaScript distinguishes expressions and statements. A statement is (roughly) an instruction, an action.

if, while, for, const are examples of statements. They perform actions or control actions, but don't resolve to values.

Optional reading


Lesson transcript

Look at this simple line of code:

const x = 5;

You know exactly what's going on, right? Create a new constant named x, put the value 5 in it. Not much to it.

Here is another line of code:

const y = getAnswer();

Create a new constant named y, put inside whatever value getAnswer function returns. Now, imagine this getAnswer is actually a huge and extremely complicated function with millions of lines of code, and it takes 12 years to compute.

How different are these lines of code? Well, it turns out that in computer science a much more powerful question is usually "how similar are these?".

And, the answer is, of course, "it depends".

If you think in terms of what is actually, literally going on — they are not similar at all. One is setting a number value, another one is calling an external function. We know very well this is not the same thing. We know about functions, and arguments, and all that stuff.

But sometimes it's useful to think in other terms, on another level. Sure, running and flying a plane are very different activities, but on a certain level they are similar — both are about moving from point to point.

These two lines are similar because on the right side of the equal sign there is an expression in both cases. Expression is a piece of code that resolves to a value. In other words, becomes a value. I know, 5 is already a value, but for the language interpreter it's an expression that resolves to the value 5. Another expression that resolves to the value 5 is 2 + 3, for example.

A function call getAnswer() is also an expression, because this function will return something. So, this call will be replaced with the value it returns. In other words, the function call will be resolved to a value, therefore it's an expression.

Not everything in the code becomes a value. So, not everything in the code is an expression, although, most things are.

JavaScript distinguishes expressions and statements. A statement is an instruction, an action. Remember conditions with if, loops with while and for — all those are statements, because they just perform actions and control actions, but don't become values.

Is this one of those obscure textbook technicalities? Might seem that way, but it's actually very important to understand and see the difference between expressions and statements.

Seeing expressions helps you understand the process of computation. Take a look at an example:

12 + square(7 + 5) + square(square(2));

This expression consists of multiple subexpressions.

First one — 12 — resolves to 12. Next one consists of multiple subexpressions:

  • 7 resolves to 7
  • 5 resolves to 5
  • 7 + 5 resolves to 12
  • square(12) resolves to 144

At this point in the process JavaScript sees the following picture:

12 + 144 + square(square(2));

It's not done yet, there are still things to resolve. It will continue until the whole expression is resolved to a single value.

square(square(2)) resolves like so:

  • 2 resolves to 2
  • square(2) resolves to 4
  • square(4) resolves to 16

Let's look inside the interpreter's mind again:

12 + 144 + 16;

All the inside expressions are resolved, so now the addition happens in two steps:

12 + 144 + 16;
156 + 16;
172;

This whole expression is now resolved.

By the way, addition operator has left-associativity. This means that in the case of multiple additions, the process happens from left to right, that's why we first see 12 + 144 and then 156 + 16.

You can't put statements where expressions are expected. For example, passing a const statement as a function argument will produce an error. Or trying to assign the if statement to a variable. This just doesn't make sense in the language, because only expressions are expected in these cases:

console.log(const x);   // error!
let b = if (x > 10) { return 100; };    // error!

Having this knowledge in mind, you will soon become the owner of two important superpowers:

  1. You will be able to see that most of the code, even that million-lines-12-year function, is just a bunch of things that become values.
  2. You will be able to notice when code just won't work because it doesn't make sense in terms of expressions-vs-statements.