Basic usage

ES6 allows functions to be defined using arrows (=>).

var f = v => v;
Copy the code

The arrow function above is equivalent to:

var f = function(v) {
  return v;
};
Copy the code

If the arrow function requires no arguments or more than one argument, use a parenthesis to represent the argument part.

var f = () => 5; Var f = function () {return 5}; var sum = (num1, num2) => num1 + num2; Var sum = function(num1, num2) {return num1 + num2; };Copy the code

If the arrow function has more than one statement in its code block, enclose them in braces and return them with a return statement.

var sum = (num1, num2) => { return num1 + num2; }
Copy the code

Because braces are interpreted as blocks of code, if an arrow function returns an object directly, parentheses must be placed around the object.

var getTempItem = id => ({ id: id, name: "Temp" });
Copy the code

Arrow functions can be used in conjunction with variable destruction.

const full = ({ first, last }) => first + ' ' + last; Function full(person) {return person.first + "+ person.last; }Copy the code

Use caution points

The arrow function has several uses with caution.

(1) The this object inside the function is the object at which it is defined, not the object at which it is used.

(2) Cannot be used as a constructor, that is, cannot use the new command, otherwise an error will be thrown.

(3) You can’t use arguments. This object does not exist in the function body. If you do, use the Rest argument instead.

(4) Yield cannot be used, so arrow functions cannot be used as Generator functions.

This is fixed, not because the arrow function has a mechanism to bind this, but because the arrow function does not have its own this, so the inner this is the outer code block's this. Because it does not have this, it cannot be used as a constructor.Copy the code

In addition to this, the following three variables also don’t exist in the arrow function, pointing to the corresponding variables of the outer function: arguments, super, and new.target.

function foo() {
  setTimeout(() => {
    console.log('args:', arguments);
  }, 100);
}

foo(2, 4, 6, 8)
// args: [2, 4, 6, 8]
Copy the code

In the above code, the arguments variable inside the arrow function is actually the arguments variable for the function foo.

In addition, since the arrow function does not have its own this, it cannot of course use call(), apply(), or bind() to change the direction of this.

(function() {
  return [
    (() => this.x).bind({ x: 'inner' })()
  ];
}).call({ x: 'outer' });
// ['outer']
Copy the code

In the above code, the arrow function does not have its own this, so the bind method is invalid. The inner this points to the outer this.

The JavaScript language’s This object has long been a headache, and using this in object methods must be done with great care. The arrow function “bind” this largely solves this problem.

The function

Arrow functions can bind this, greatly reducing the need to explicitly bind this (call, apply, bind). However, arrow functions are not suitable for all situations, so ES7 introduces the function bind operator to replace call, apply, and bind. Although this syntax is still a proposal in ES7, the Babel transcoder already supports it.

The function-binding operators are two double colons (::) side by side, with an object on the left and a function on the right. The operator automatically binds the object on the left as the context (this object) to the function on the right.

foo::bar; // Equivalent to bar.bind(foo); foo::bar(... arguments); // equivalent to bar.apply(foo, arguments); const hasOwnProperty = Object.prototype.hasOwnProperty; function hasOwn(obj, key) { return obj::hasOwnProperty(key); }Copy the code

If the left side of the double colon is empty and the right side is a method of an object, it binds that method to that object.

var method = obj::obj.foo; Var method = :obj.foo; let log = ::console.log; // Var log = console.log.bind(console);Copy the code

Since the double colon operator returns the same object, we can use the chain notation.

Tail-call optimization

What is a tail call?

The Tail Call refers to the last step of a function that is to Call another function.

function f(x){
  return g(x);
}
Copy the code

In the above code, the last step of function F is to call function G, which is called a tail call.

Tail Call optimization preserves only the call frames of the inner functions. If all functions are tail calls, then it is perfectly possible to have only one call frame item per execution, which would save a lot of memory. This is what tail-call optimization is all about.Copy the code

Strict mode

Tail-call optimization in ES6 is only enabled in strict mode, not in normal mode.

This is because, in normal mode, there are two variables inside the function that trace the call stack of the function.

  • func.arguments: returns the argument to the function when it is called.
  • func.caller: returns the function that called the current function.

When tail-call optimization occurs, the call stack of the function is overwritten, so the above two variables are distorted. Strict mode disables both variables, so tail-call mode only works in strict mode.

function restricted() { "use strict"; restricted.caller; / / error restricted. The arguments; Restricted ();Copy the code
Copy the code

Arrow functions compared to regular functions

An arrow function differs from a normal function in two ways:

  • The construction of the following variables is lexical:arguments , super , this , new.target
  • Cannot be used as a constructor:There is no internal method[[Construct]]This method allows ordinary functions to passnewCall), neitherprototypeProperties. As a result,new (() => {})An error is thrown.

Aside from those accidents, arrow functions are not significantly different from normal functions. For example, Typeof and Instanceof produce the same result:

> typeof () => {}
//'function'
> () => {} instanceof Function
//true

> typeof function () {}
//'function'
> function () {} instanceof Function
//true
Copy the code

The exceptions are function expressions and object literals, which must be enclosed in parentheses because they look like function declarations and code blocks.

Copy the code