FXAMN FXAMN - 2 months ago 7
Javascript Question

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

What is the difference between a statement and a expression? How can i know each one is?

Why void transform this:

void function() {

}();


into an expression?

And why this works:

something((something) => something + 2);


and this don't:

something((something) => if (something) { something + 2 });


?

Thanks!!

Answer

Statements and expressions are different language units. What's probably tripping you up is that JavaScript, unlike some other languages, has what the spec calls ExpressionStatement: It can treat any expression as a statement (but it cannot treat statements as expressions). So for instance, this is valid JavaScript:

flag && console.log("Hi there");

...whereas in (say) Java that wouldn't be valid, because while Java has some specific statements to allow for specific expression-like things (method calls, for instance), it doesn't have JavaScript's overall ExpressionStatement.

Why void transform this:

void function() {

}();

into an expression?

Because void is an operator. It evaluates its operand (whatever follows it), and then sets its result to undefined. It's not at all related to the void that you see in languages like C, C++, Java, or C#. So the whole thing is an ExpressionStatement. The only reason you need the void there is that without it, when the parser is expecting to see a statement, the keyword function puts the parser into a state where it's expecting a function declaration, not an expression. (You can use any operator, not just void, to put the parser into expression state; details in this question and its answers.)

And why this works:

something((something) => something + 2);

and this don't:

something((something) => if (something) { something + 2 });

Because of the way arrow functions are defined by the specification. There are two forms of arrow function:

  • Ones with a concise body (no {})
  • Ones with a verbose body

Concise example:

array.sort((a, b) => a - b);

Equivalent verbose example:

array.sort((a, b) => {
    return a - b;
});

Arrow functions with concise bodies require that the body be an expression because, as you can see above, they return the result of the expression. You can't use a statement there for the same reason you can't use a statement other places an expression is required: A result value is needed for the implicit return statement. Your second example, translated to a verbose body, is this:

something((something) => {
    return if (something) { something + 2 };
});

...which demonstrates why it didn't work: You have an if after return, but the return statement requires an operand (expression) or statement terminator instead.