11

For the past few hours I have been trying to find the difference between the 3, not just the difference, I also have been trying to find out which are sort of synonymous, MDN calls all declarations "statements", so I presume that is true. However, none of the articles and SO questions I read provided me with a cheatsheet of sorts to distinguish between the 3 (or the 2, expressions vs statements).

Something I have noticed with statements is that they all somehow involve a special JavaScript keyword like break or for or var. The articles say that an expression evaluates to something, while a statement performs an action. What is a function then ? Is it a statement-expression hybrid (since it both performs an action when called, and returns a value) ? Right now, I am assuming that this is not the case since a function call does not involve a JavaScript keyword.

And then there are declarations, is every declaration also a statement ?

I am also aware of expression statements like 20 + 5 * 2 / 3;, but aren't these virtually useless ? Why would anyone pollute their code with a line like this ?

I would be more than glad if someone could ask the above questions (or at least some of them), or if someone could provide me with some sort of a cheatsheet. Why is there so little material on a topic that appears to be so simple in such a popular language ?

doubleOrt
  • 2,149
  • 10
  • 26
  • *"I am also aware of expression statements like `20 + 5 * 2 / 3;`, but aren't these virtually useless ?"* Here are two expression statements you have probably seen before and not find them useless: variable assignments (`foo = 42;`) and function calls (`bar();`). – Felix Kling Sep 21 '17 at 20:23
  • 1
    Shameless plug: http://astexplorer.net/ lets you inspect the AST of a JavaScript program. – Felix Kling Sep 21 '17 at 20:25
  • Thanks! <3 I am printing something with my laptop right now but i have much to say about your first comment as well, will be back in a few minutes. – doubleOrt Sep 21 '17 at 20:27
  • And here we are, more than 3 years later, and Felix is still waiting. Who knows what happened? Maybe the print job never stopped. Maybe doubleOrt decided programming was not what they wanted to do with their life after all. Maybe they rode off into the sunset on a white pony. We'll never know. – Niels Bom Dec 07 '20 at 23:18
  • 1
    @NielsBom I am just coming back to programming actually, I wonder how much the javascript scene has changed. 2 years ago, React and Angular were the most popular frameworks, what's it like now? – doubleOrt Dec 08 '20 at 07:43
  • Check out the [Stack Overflow Developer Survey](https://insights.stackoverflow.com/survey/2020) – Niels Bom Dec 13 '20 at 20:39

3 Answers3

14

There are standard definitions of these terms that all languages, including JS, follow. My takes on them are the following:

  • An expression produces a value and can be written wherever a value is expected.

  • A statement on the other hand is is a standalone unit of execution. It does not return anything.

  • A declaration is a statement in which a value is assigned to a variable.

  • All declarations are statements, but not all statements are declarations.

  • Most statements and all declarations contain expressions.

Javadoc also gives nice, succinct definitions:

An expression is a construct made up of variables, operators, and method invocations, which are constructed according to the syntax of the language, that evaluates to a single value.

Statements are roughly equivalent to sentences in natural languages. A statement forms a complete unit of execution.

Now, your theory on keywords being necessarily involved is incorrect. Here is a statement that includes a keyword:

break;

And here is one that does not:

foo();

In the first example I execute a break, whereas in the second one I call a function. Both are statements, however only one includes any special keyword.

A function is not a statement. A function call is a statement, as demonstrated above. In the case of a function that returns something, the call can also be a declaration:

var bar = foo();

And for your final question, the reason there is so little material out there on this is because this is merely an issue of semantics. People do not linger on the exact definitions of these terms.

For further clarification, I recommend taking a look at this blog post by Axel Rauschmayer that specifically talks about the difference between statements and expressions in JS.

Community
  • 1
  • 1
stybl
  • 8,580
  • 3
  • 24
  • 48
  • Why is a function not a statement ? Isn't it just a declaration? – doubleOrt Sep 21 '17 at 19:55
  • 1
    The function itself *can* be considered a declaration, but that is language specific. – stybl Sep 21 '17 at 19:56
  • I appreciate the distinctions. Goes right up there with parameters vs arguments. It's worth knowing and using correctly when we talk about code, so that we can be precise and concise. – TinkerTenorSoftwareGuy Sep 21 '17 at 19:57
  • I am assuming `foo ();` is what is called an "expression statement". If so, then aside from these expression statements, are there any other statements that don't contain a keyword ? – doubleOrt Sep 21 '17 at 19:59
  • In C and C derived languages, expression statements are defined as basically expressions with a semicolon at the end. In the JS world however, they are mostly synonymous with statements as I have defined them in my answer. – stybl Sep 21 '17 at 20:01
  • The other comment anwered my last qiestion, a block statement doesn't involve a keyword either :) – doubleOrt Sep 21 '17 at 20:02
  • Since we are being technical about definitions here, it is worth noting that "block statements" are really just statements and definitions bunched up together between braces. – stybl Sep 21 '17 at 20:04
  • In JavaScript, declarations are not statements, though there are often treated similarly. – Felix Kling Sep 21 '17 at 20:19
  • The Javadoc definitions are excellent. And could you elaborate on your comment _"In C and C derived languages, expression statements are defined as basically expressions with a semicolon at the end. In the JS world however, they are mostly synonymous with statements as I have defined them in my answer."_, from what i see of your answer, expression statements ARE just expressions with a semicolon at the end. – doubleOrt Sep 21 '17 at 22:09
  • That is a very simplistic way of defining them. It is like defining a question as just any sentence with a question mark at the end. While this definition is not wrong, per-se, there is a lot more to it. – stybl Sep 22 '17 at 13:58
  • A declaration is only optionally initialized to a value (unless it's a const). It is still a declaration if no value is assigned. – Dan Apr 30 '18 at 07:28
5

For the past few hours I have been trying to find the difference between the 3, not just the difference, I also have been trying to find out which are sort of synonymous, MDN calls all declarations "statements", so I presume that is true.

A declaration is any construct that "declares" a variable name into existence at compile/load time before the program executes. All declared names in their respective scopes are therefore known in advance.

Statements and expressions differ from each other in that the former does not produce a value a result, whereas the latter does. So an expression may be used anywhere a value is expected, and a statement may not be used in those places.

An expression statement is one where the statement is a single expression, or several included in an expression that requires zero or more sub-expressions. While the expression(s) produce a result, the statement does not.

Here's an expression:

x = foo() + 2

A full expression statement could be explicitly shown by adding a semicolon to the end.

x = foo() + 2;

The first example can be wrapped in a set of parens, because the parens as a grouping operator expects an expression, often provided as several expressions joined by the comma operator.

The second example can not be wrapped in parens (if you include the semicolon) because then it is a statement, and does not produce a value, which the grouping operator expects to receive and return as its own value.

Something I have noticed with statements is that they all somehow involve a special JavaScript keyword like break or for or var.

While most statements do involve a keyword, not all do. Most notably, the block statement has no keyword. Instead it uses a set of curly braces to delimit its start and end.

The articles say that an expression evaluates to something, while a statement performs an action. What is a function then ? Is it a statement-expression hybrid (since it both performs an action when called, and returns a value) ? Right now, I am assuming that this is not the case since a function call does not involve a JavaScript keyword.

There are three kinds of functions in JS. If you're talking about the ones that use the function keyword, then the may be either a declaration or an expression depending on its context.

If the function is used where an expression would be expected, then it's evaluated as an expression that returns a new function object. If not, then it is expected to be a declaration, which basically creates a variable with the function object assigned to it. As a declaration, a function name is required (for the variable name). As an expression, it's optional.

I am also aware of expression statements like 20 + 5 * 2 / 3;, but aren't these virtually useless ? Why would anyone pollute their code with a line like this ?

If the resulting value is ignored, it would be useless, given that example. But here's another expression statement.

foobar();

Now we have a side effect from the function call, which is most likely desired and useful.

llama
  • 2,385
  • 7
  • 9
  • 2
    By the way, I see a distinction between a statement and a declaration, where statements are part of the runtime, and declarations happen once, before any code is executed. One may say that they're the same because a function that executes more than once will need to create that declared variable more than once, but while the information from the declaration may be utilized every time the function is executed, the declaration itself occurs while the program is being parsed, long before any code runs. The *information* from those declarations is provided each time an execution context is set up. – llama Sep 21 '17 at 20:05
  • To add to the confusion, what's the difference between `var a;` and `var a = 2;`? I'd assume, the first is a `declaration`. In the second, two things are happening: `declaration` and `assignment`, and as a whole, it's a `statement`. There is no `expression`, just a `value`. If I wrote `var a = 2 + 1;`, then we would have a `declaration`, an `expression`, and a `statement`. Am I wrong? – akinuri Oct 09 '20 at 07:32
  • On second thought, if we were to refer to _"standalone unit of execution"_ (above) as statement's definition, `var a;` is a declaration, but also a statement. So it seems statement is a more generic/higher concept than declaration/expression. – akinuri Oct 09 '20 at 07:41
2

Let's talk about expressions first. As you say, an expression is something that evaluates to a value. A function is a value. A function call, on the other hand, is an expression.

I don't agree with the characterization of a statement as something that "performs an action". As you say, calling a function involves running the function body, which consists of statements and declarations, so it performs actions "on the inside".

A better way to look at it is that expressions, statements, and declarations are syntactic categories. They arise from trying to describe the structure of the JavaScript grammar. See e.g. the ECMAScript 8 specification on expressions, statements, and declarations.

An expression statement like 20 + 5 * 2 / 3; is indeed useless because it has no effects, and the only point of a statement is its effects. But there are other kinds of much more useful expression statements:

  • a function call: foo();
  • assignment: x = 42; (= is an operator and can be used in expressions)
  • increment/decrement: i++; (similarly, ++ is an operator)

Statements other than expression statements tend to start with a special keyword to avoid syntactic ambiguity: The parser wants to be able to tell what kind of construct it is dealing with right from the start. Hence we get:

  • if statements: if (EXPR) STMT
  • while statements: while (EXPR) STMT
  • return statements: return; or return EXPR;
  • etc.

However, there are some statements that don't start with a keyword:

  • the empty statement: ;
  • a block: { ... }

Finally, declarations. In JavaScript the distinction between statements and declarations is somewhat arbitrary. The grammar distinguishes between the two, but in practice you can often treat them the same (e.g. the contents of a block statement are defined as a sequence of statement list items, and a statement list item is defined to be either a statement or a declaration). Declarations include:

  • function declarations: function foo() { ... } (including variants such as generators (function* foo() { ... }) and asynchronous functions (async function foo() { ... }))
  • let and const
  • class declarations

(But for some reason var foo; is classified as a statement, not a declaration.)

melpomene
  • 79,257
  • 6
  • 70
  • 127
  • Are you sure about the `var` part at the end of your answer ? See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements#Declarations – doubleOrt Sep 21 '17 at 21:39
  • @Taurus Yes, see http://www.ecma-international.org/ecma-262/8.0/index.html#prod-VariableStatement. – melpomene Sep 21 '17 at 21:46
  • Weird, also any idea why a semicolon is a statement? This truly is weirder than i had thought. – doubleOrt Sep 21 '17 at 21:49