Standard vs arrow functions
Standard
- Traditional
function double(x) { return x * 2 }
- Anonymous variation.
const double = function (x) { return x * 2 }
Arrow
JS now supports “arrow” functions using =>
syntax.
You could already use function() {}
syntax to make an anonymous function declared and use immediately, but arrow functions are shorter, and also work differently in some cases.
Resources
- Arrow function expressions on MDN docs.
An arrow function expression is a compact alternative to a traditional function expression, but is limited and can’t be used in all situations.
Differences and limitations:
- Does not have its own bindings to
this
orsuper
, and should not be used as methods.- Does not have
new.target
keyword.- Not suitable for
call
,apply
andbind
methods, which generally rely on establishing a scope.- Can not be used as constructors.
- Can not use
yield
, within its body.
Anonymous functions
This is like using ->
in Java or lambda
in Python.
myArray.map(function(x) { return x * 2 })
Arrow functions makes this lighter:
myArray.map((x) => x * 2)
Named arrow functions
Some people like to use arrow functions to create an anonymous function and then assign it a variable name, as below.
- One line.
const greet = () => console.log("Hello"); const double = x => x * 2; // Dropping brackets is allowed. const multiply = (x, y) => x * y;
- On multiple lines. Be explicit with
return
expression.const double = x => { return x * 2 }; // Useful if you want to do something before the `return`. const multiply = (x, y) => { console.log({x, y}) return x * y; }
- Return an associative array:
// Use brackets to make it an expression. const double = (x) => ( { myKey: x * 2 } ); // Or use `return` inside a block. const double = (x) => { return { myKey: x * 2 } }; // This is NOT valid. // const foo = (x) => { myKey: x * 2 };
Differences
A major difference is that this
behaves differently. An arrow function does not come with this
in scope, at the least when used outside a class.
Arrow functions do not have their own
this
const myObj = {
i: 10,
b: () => console.log(this.i, this), // uses global scope so `this` is `window`
c: function() {
// Uses `myObj` as the scope.
console.log(this.i, this);
}
}
Another difference is that while standard functions are hoisted so you can declare and use them in any order in your code, using arrow functions to make a variable instead actually means you have to declare and call functions in order.
Arrow functions have lighter syntax, but in cases where use more than one line and assign a function to variable, the code is actually longer with arrow functions.
Compare these two:
-function getCookie(cookieName) {
+const getCookie = (cookieName) => {
Arrow functions also makes it harder to separate plain variables from function variables when scanning the code visually, as the function
keyword is gone.