JS Arrow Functions
Tags: javascript
Published: 2020-07-31 02:26:49

<!-- TOC -->

- [Syntax](#syntax)
    - [Basic Syntax](#basic-syntax)
    - [`this` Values](#this-values)
    - [`new` Operator](#new-operator)
    - [`prototype` Property](#prototype-property)
    - [`yield` Keyword](#yield-keyword)
- [Libraries of Interest](#libraries-of-interest)
    - [Underscore.js](#underscorejs)
    - [Immutable.js](#immutablejs)
- [References](#references)

<!-- /TOC -->

> 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

```javascript
(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 }

```

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

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

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

> 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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Rest_parameters)** and **[default parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)** are supported:

```javascript
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, …, paramN = defaultValueN) => { statements }
```

**Destructuring** within the parameter list is also supported

```javascript
var f = ([a, b] = [1, 2], { x: c } = { x: a + b }) => a + b + c
f() // 6
```

### `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`.

```javascript
var Foo = () => {}
var foo = new Foo() // TypeError: Foo is not a constructor
```

### `prototype` Property

Arrow functions do not have a `prototype` property.

```javascript
var Foo = () => {}
console.log(Foo.prototype) // undefined
```

### `yield` Keyword

The [yield](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/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](https://underscorejs.org/)

**[Documentation](https://underscorejs.org/)**

> 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](https://immutable-js.github.io/immutable-js/)

**[Documentation](https://immutable-js.github.io/immutable-js/docs/#/)**

> 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

- **[MDN: Arrow Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)**
- **[Mozilla Hacks: Arrow Functions In Depth](https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/)**