Take a look at the ES6 unarrow function

Basic Grammar

(param1, param2, …, paramN) => { Expressions }
(param1, param2, …, paramN) => Expressions
// Equivalent to:(param1, param2, …, paramN) =>{ return Expressions; }

// The parentheses are optional when there is only one argument:
(singleParam) => { Expressions }
singleParam => { Expressions }

// Functions without arguments should be written as a pair of parentheses.
() => { Expressions }

Shorter expressions

var elements = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium'];

elements.map(function(element) {
  return element.length;
}); // Return array: [8, 6, 7, 9]

// The above common function can be rewritten as the following arrow function
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// 当箭头函数只有一个参数时,可以省略参数的圆括号
elements.map(element => {
  return element.length;
}); // [8, 6, 7, 9]

// When the function body of an arrow function has only one `return` statement, the `return` keyword and the brackets in the method body can be omitted
elements.map(element => element.length); // [8, 6, 7, 9]

There is no separate this

Before the arrow function appears, each new function defines the this value of this function according to how it was called.

  • If the function is a constructor, this pointer points to a new object
  • In the case of a function call in strict mode, this points to undefined
  • If the function is a method of an object, then its this pointer points to the object
function Person() {
  // The Person() constructor defines `this` as its own instance.
  this.age = 0;
  setInterval(function growUp() {
    // In non-strict mode, the growUp() function defines `this` as a global object
    // is not the same as the `this` defined in the Person() constructor.
    this.age++; // Here this.age is undefined
  }, 1000);
}
var p = new Person();

The Person() constructor defines this as its own instance.

function Person() {
  var that = this;
  that.age = 0;
  setInterval(function growUp() {
    // The callback refers to a `that` variable, whose value is the expected object.
    that.age++;
  }, 1000);
}

The arrow function does not create its own this, it only inherits this from a higher level in its own scope chain, so in the code below, the this inside the function passed to setInterval has the same value as the this in the enclosing function.

function Person(){
  this.age = 0;
  setInterval(() => {
    this.age++; // this correctly points to the p instance
  }, 1000);
}
var p = new Person();

Called by call or apply

Since arrow functions do not have their own this pointer, when calling a function via the call() or apply() methods, only arguments can be passed (they cannot bind to this) and their first argument is ignored. (This phenomenon also holds for the bind method)

var adder = {
  base: 1,

  add: function(a) {
    console.log(arguments)
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    console.log(arguments)
    var f = v => v + this.base;
    var b = {
      base: 2
    };

    return f.call(b, a);
    // return f.apply(b, [a]);
    // return f.bind(b, a)();
  }
};

console.log(adder.add(1,2)); // Output 2
console.log(adder.addThruCall(1)); // Still output 2

Briefly explain the usage and difference between call, apply and bind

There is no difference between them in terms of function, they both change the point of this, the difference between them mainly lies in the implementation of the method form and the difference in parameter passing. call and apply methods are executed immediately after the call. The bind method returns to the original function after the call, and needs to be called again.

var p = {
  a: 1,
  add: function(b) {
    console.log(this.a + b);
  }
}
var p2 = {
  a: 2
}
p.add(2); // 3
p.add.call(p2, 2);    // 4
p.add.apply(p2, [2]); // 4
p.add.bind(p2, 2)();  // 4
  1. The first parameter of apply, call, and bind is the object that this points to, but apply has only two parameters, and the second parameter is an array, and all the parameter values that need to be transferred must be put into the array. As for call and bind, the parameters are separated by commas.
  2. apply, call returns a value, while bind returns a function, you need to execute the function to get the value.

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

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

Arrow functions do not have a prototype attribute

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

Arrow functions do not bind Arguments objects

function foo(n) {
  return  arguments[0] + n
}
var f = () => arguments[0] + n; 

console.log(foo(1)) ; // 2
console.log(foo(2,1)) ; // 4

console.log(f(1)) ; // 2//Uncaught ReferenceError: arguments is not defined

The yield keyword cannot normally be used in an arrow function (unless it is nested within an allowed function). Therefore, arrow functions cannot be used as function generators

yield keyword.

  • Can only be used inside Generator functions
  • Run .next() and pause when a yield command is encountered
  • The return value of .next() represents a status {value,done}
  • Run .next() again, resuming from (after) the previously encountered yield [expression]
  • When .next() is passed, the entire yield [expression] is replaced with the passed parameter.

Function Body

Arrow functions can have a “short form” or the common “block form”.
In a short form, only one expression is needed, with an implicit return value. In a block, an explicit return statement must be used.

var func = x => x * x;
// Abbreviated functions Omit return

var func = (x, y) => { return x + y; };
// General Writing Explicit Return Values

Return object literals

// Remember that returning object literals with a simple syntax like params => {object:literal} doesn't work.
var func = () => { foo: 1 };

// Calling func() returns undefined!
console.log(func()) // (call returns undefined)

var func = () => { foo: function() {} };
// SyntaxError: function statement requires a name. This is because the code inside the parentheses ({}) is parsed as a series of statements (i.e., foo is considered a label, not a component of an object literal).

// So, remember to wrap the object literals in parentheses.
var func = () => ({foo: 1});

line feed

Arrow functions do not have line breaks between arguments and arrows.

var func = ()
       => 1;
// error is reported
However, line breaks can be achieved by following '=>', or by using '( )', '{ }', as follows.

var func = (a, b, c) =>
  1;

var func = (a, b, c) => (
  1
);

var func = (a, b, c) => {
  return 1
};

var func = (
  a,
  b,
  c
) => 1;

// There will be no syntax errors

Arrow functions can also use conditional (ternary) operators

var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;

Summary

  1. arrow function this for the parent scope of this, not when called this
  2. arrow function can not be used as a constructor, can not use new
  3. The arrow function does not have arguments
  4. arrow function called by call and apply, will not change this point, only pass in parameters
  5. The arrow function does not have the prototype property
  6. Arrow function can not be used as Generator function, you can not use the yield keyword
  7. arrow function returns an object, to add a parenthesis

Leave a Reply