DEV Community

Cover image for JS Arrow Functions
Connor Dillon
Connor Dillon

Posted on

JS Arrow Functions

Arrow functions are a syntactically compact alternative to regular function expressions.

  • Lacks binding to this, arguments, super, and new.target keywords.
  • Ill suited as methods.
  • Cannot be used as constructors.
  • An arrow function with a block body does not automatically return a value. Use a return statement for that.wa

Syntax

Basic Syntax

(param1, param2, , paramN) => { statements }
// equivalent to: => { return expression; }
(param1, param2, , paramN) => expression

(singleParam) => { statements }
// Parentheses are optional when there's only one parameter name:
singleParam => { statements }

// The parameter list for a function with no parameters should be written with a pair of parentheses.
() => { statements }

Enter fullscreen mode Exit fullscreen mode

Parenthesize the body of a function to return an object literal expression:

;(params) => ({ foo: bar })

// Always wrap plain objects in parentheses!
var chewToys = puppies.map((puppy) => {}) // BUG!
var chewToys = puppies.map((puppy) => ({})) // ok
Enter fullscreen mode Exit fullscreen mode

Unfortunately, an empty object {} and an empty block {} look exactly the same. The rule in ES6 is that a left bracket { immediately following an arrow is always treated as the start of a block, never the start of an object. The code puppy => {} is therefore silently interpreted as an arrow function that does nothing and returns undefined.

Even more confusing, an object literal like {key: value} looks exactly like a block containing a labeled statement—at least, that’s how it looks to your JavaScript engine. Fortunately { is the only ambiguous character, so wrapping object literals in parentheses is the only trick you need to remember.

Rest parameters and default parameters are supported:

(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, , paramN = defaultValueN) => { statements }
Enter fullscreen mode Exit fullscreen mode

Destructuring within the parameter list is also supported

var f = ([a, b] = [1, 2], { x: c } = { x: a + b }) => a + b + c
f() // 6
Enter fullscreen mode Exit fullscreen mode

this Values

Arrow functions do not have their own this value.
The value of this inside an arrow function is always inherited from the enclosing scope.

In ES6, this hacks mostly go away if you follow these rules:

  • Use non-arrow functions for methods that will be called using the object.method() syntax. Those are the functions that will receive a meaningful this value from their caller.
  • Use arrow functions for everything else.

new Operator

Arrow functions cannot be used as constructors and will throw an an error when used with new.

var Foo = () => {}
var foo = new Foo() // TypeError: Foo is not a constructor
Enter fullscreen mode Exit fullscreen mode

prototype Property

Arrow functions do not have a prototype property.

var Foo = () => {}
console.log(Foo.prototype) // undefined
Enter fullscreen mode Exit fullscreen mode

yield Keyword

The yield keyword may not be used in an arrow function's body (except when permitted within functions further nested within it). As a consequence, arrow functions cannot be used as generators.

Libraries of Interest

Underscore.js

Documentation

Underscore provides over 100 functions that support both your favorite workaday functional helpers: map, filter, invoke — as well as more specialized goodies: function binding, javascript templating, creating quick indexes, deep equality testing, and so on.

Immutable.js

Documentation

Immutable.js provides many Persistent Immutable data structures including: List, Stack, Map, OrderedMap, Set, OrderedSet and Record.

Immutable.js also provides a lazy Seq, allowing efficient chaining of collection methods like map and filter without creating intermediate representations. Create some Seq with Range and Repeat.

References

Top comments (0)