Skip to content
Theory · First program · lesson 5 of 7

Order of calculation

In the previous lesson we wrote the function add and called it once per line. But one line can hold several arithmetic signs and calls at once. Then you need to know in what order JavaScript runs them.

Let's go back to the cookbook. The step "pour the sauce over the fish" cannot be done right away: the cook opens the sauce page, makes the sauce, and only then returns to the fish. The outer step waits until the inner one is done.

Let's look at a program where every line holds several actions:

JavaScript
function add(a, b) {
    return a + b;
}

console.log(1 + 2 * 3); // 7
console.log((1 + 2) * 3); // 9
console.log(10 - 4 - 3); // 3
console.log(add(add(1, 2), 3)); // 6
console.log(add(2 * 3, 1)); // 7

The first three lines follow the rules of the arithmetic signs, and the last two follow the rule of calls: the arguments are worked out first, then the call itself. Let's go through both rules.

Arithmetic signs

Numbers work with the signs +, - and *. Three rules set the order:

  • as in math, * runs before + and -;
  • signs of the same level, such as + and -, run one by one from left to right;
  • parentheses change that order.

By these rules, JavaScript works out the first three lines of the example like this:

  1. 1 + 2 * 3: first 2 * 3, and 1 + 6 gives 7.
  2. (1 + 2) * 3: the parentheses make it add 1 + 2 first, and 3 * 3 gives 9.
  3. 10 - 4 - 3: subtractions go from left to right, so first 10 - 4 gives 6, and then 6 - 3 gives 3.

If you are unsure about the order, add parentheses. Parentheses around what would run first anyway do not change the result: 1 + (2 * 3) also gives 7.

Nested calls

A call can be passed to another call as an argument. This is called a nested call: the inner call runs first, and its result becomes an argument of the outer one. Like the sauce: the outer add does not start until the inner one returns a finished number.

Press "Next step" and watch the run go into add and come back with a finished number. Notice that the inner call ends before the outer one.

LiveA function call step by stepstep 1 of 10 · frames: 1

Lines 1–3 only declare add, so the run starts with the call add(2, 3).

A frame is where one call's parameters live

The last two lines of the first example run like this:

  1. add(1, 2) returns 3, then add(3, 3) returns 6.
  2. An argument can be a calculation too: first 2 * 3 is worked out as 6, and the function receives 6 and 1.

The sauce picture has a limit. A cook can make the sauce in advance, in the morning. JavaScript has no such choice: the arguments are worked out one by one, left to right, right before the call. For example, in add(add(1, 2), add(3, 4)) first add(1, 2) gives 3, then add(3, 4) gives 7, and only then the outer add(3, 7) returns 10.

Interviewers often show beginners a line with a call inside a call and ask what it prints. Find the innermost call and work from the inside out.

Common mistake

The function should add two numbers and double the sum, but the parentheses are missing:

JavaScript
function doubleSum(a, b) {
    return a + b * 2; // ✗
}

console.log(doubleSum(2, 3)); // 8

There is no error message, but the program prints 8 instead of 10: * ran before +, and only b was doubled. The fix is to put the sum in parentheses: return (a + b) * 2;.

Key points

  • * runs before + and -, signs of the same level go from left to right, and parentheses change the order.
  • The arguments are worked out first, then the call itself runs.
  • In a nested call, the inner call ends before the outer one, and its result becomes an argument.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way