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:
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)); // 7The 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 + 2 * 3: first2 * 3, and1 + 6gives7.(1 + 2) * 3: the parentheses make it add1 + 2first, and3 * 3gives9.10 - 4 - 3: subtractions go from left to right, so first10 - 4gives6, and then6 - 3gives3.
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.
1function add(a, b) {2 return a + b;3}4 5console.log(add(2, 3));6console.log(add(add(1, 2), 3));
Lines 1–3 only declare add, so the run starts with the call add(2, 3).
The last two lines of the first example run like this:
add(1, 2)returns3, thenadd(3, 3)returns6.- An argument can be a calculation too: first
2 * 3is worked out as6, and the function receives6and1.
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:
function doubleSum(a, b) {
return a + b * 2; // ✗
}
console.log(doubleSum(2, 3)); // 8There 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.