It can be difficult to determine what the final value for an expression is, especially when:
- It's more than a few lines long
- You didn't write it (or you wrote it a while ago)
- It doesn't have comments
For example, can you tell what value is set in the below example?
position
js
const myPosition = [960, 540];myPosition * 2;[0, 0];const otherPosition = [500, 500];
js
[0, 0];
Knowing which value is set requires reading through and understanding the whole expression.
To learn more about what determines the final value for an expression, see our article on statement completion values.
Using a return statement
Ideally you would be able to use a return
statement, as if the expression was the body of a function:
js
const myPosition = [960, 540];myPosition * 2;return [0, 0];const otherPosition = [500, 500];
js
[0, 0];
Which has the benefit of explicitly setting what value is used, allowing you to scan an expression for the return
keyword and work backwards from the final value.
You can learn more about return
statements in our article on functions.
Other benefits
Using return
statements has more benefits than just being explicit, for example:
- Skipping code with early returns, without needing an
else
clause
js
if (test) {return someValue;}// more complicated codereturn somethingElse;
- Ending an expression with a function declaration
js
return bounce(3, 2);function bounce(...) {}
- Avoiding polluting the global scope when using
var
declarations
Wrapping expressions in a function
Using a return
statement in an expression will result in an error, as they aren't allowed outside of a function body:
js
return "Use this for the final value";
js
Error: Syntax Error: Illegal return statement
To get around this you need to wrap your expression in a function and then call it, for example:
js
function main() {return "Hello from return";}main();
js
"Hello from return";
IIFEs
While this works well, you can reduce the amount of syntax needed by using an IIFE.
IIFE stands for Immediately Invoked Function Expression.
This is a method for invoking the function as soon as it's created, by:
- Wrapping an anonymous function in parenthesis (
()
) - Followed by another pair of parenthesis to call it
For example:
js
(function () {return someValue;})();
You make a function anonymous by omitting it's name, which normally comes after the function
keyword.
You can then further reduce the amount of code by changing the function to an ES6 arrow function:
js
(() => {return "Returned!";})();
js
"Returned!";
This allows you to gain the benefits of using return
statements in your expressions, with minimal syntactical overhead.
For example, the expression from the top of this post becomes:
js
(() => {const myPosition = [960, 540];myPosition * 2;return [0, 0];const otherPosition = [500, 500];})();
js
[0, 0];
Where it's now clear what value is being used as the result of the expression.
This isn't something you need to do on every expression, but rather another technique to keep your expressions easy to read and understand.
While the examples in this post have been simple, the benefits are especially true when it comes to longer and more complicated expressions.
Blog