In ES6, there is a new way to define functions — arrow functions (=>). Arrow functions are more concise than traditional functions.
/ / ES6 syntax
const fn = v= > v;
// Traditional functions
const fn = function(v) {
return v;
}
Copy the code
Characteristics of the arrow function
(1) Syntax concise Arrow functions omit the keyword 'function' and replace it with '=>'. The parentheses represent the argument part. When there is only one argument, the parentheses can be omitted; when there is only one return statement, the 'return' and the curly braces' {} 'can be omitted. Const fn = (a, b) => {return a + b; }; // const fn = (a, b) => a + b; Const sum = [1, 2, 3, 4, 5]. Reduce ((x, y) => x + y, 0); // Const sum = [1, 2, 3, 4, 5]. Const array = [2, 4, 1, 5, 9, 7]. Sort ((x, y) => x-y); / / [1, 2, 4, 5, 7, 9] / / filter for the even Numbers in the array const array = [0, 1, 2, 3, 4, 5, 6]. The filter (x = > x % 2 = = = 0). // [0, 2, 4, 6] (2) unbind this the 'this' inside the arrow function always refers to the object on which it was defined, not the object on which it was called. ```js function Fn() { this.s1 = 0; this.s2 = 0; // Arrow function setInterval(() => this.s1++, 1000); SetInterval (function() {this.s2++; }, 1000); } var fn = new Fn(); setTimeout(() => console.log('s1= ', fn.s1), 3100); // s1= 3 setTimeout(() => console.log('s2= ', fn.s2), 3100); In the above code, Fn function has two timers set inside, respectively using arrow function and ordinary function. S1 ++ is in the arrow function, where this is Fn, so the value of fn.s1 is 3. S2 ++ is actually equal to window.s2++. Fn.s2 has not been updated once, so it is 0. So, strictly speaking, arrow functions do not create their own 'this', but inherit from one level up in their scope chain. ```js const Person = { name: 'Kimmy', age: 20, doSomething: function() { setTimeout(() => console.log(`name: ${this.name}, age: ${this.age}`), 1000); }}; Person.doSomething(); // name: Kimmy, age: 20 const Person2 = { name: 'Kimmy', age: 20, doSomething: () => { setTimeout(() => console.log(`name: ${this.name}, age: ${this.age}`), 1000); }}; Person2.doSomething(); // name:, age: undefined the only difference is that the doSomething() function is used for Person and the arrow function for Person2. In the first code, the 'this' in person.dosomething () points to the body of the function, that is, Person itself. Since the body part of the setTimeout() function is defined by the arrow function, The inner 'this' inherits the' this' (that is, 'Person') of the parent scope, thus printing 'name: Kimmy, age: 20'. In the second piece of code, the 'this' in person2.dosomething () points to the outer scope, while the parent scope of Person2 is the global scope Window. Since the body part of the setTimeout() function is defined by the arrow function when called, The internal 'this' inherits the' this' (window) scope of the 'doSomething()' function, where the name attribute is '' and the age attribute does not exist, so 'person2.dosomething ()' outputs' name ': , the age: undefined `. To sum up, the arrow function does not have its own 'this' at all, resulting in the inner' this' being the 'this' of the outer code block. Because it does not have 'this', it cannot be used as a constructor. We all know that you can change the execution body of a function by calling 'call()', 'apply()', and 'bind()'. That is, you can change the direction of 'this' in the called function. However, arrow functions do not support 'call()', 'apply()', 'bind()', etc., because arrow functions do not have their own 'this', but inherit' this' from the parent scope. ```js function fn() { return () => { console.log(`id= ${this.id}`); } } let f = fn.call({id: 1}); // id= 1 let f2 = f.call({id: 2})()(); // id = 1 let f3 = f().call({id: 3})(); // id= 1 let f4 = f()().call({id: 4}); // select * from 'this' where' this' = 'f2', 'f3' and 'f4' = 'this'; Because the inner function when the arrow function does not have its own 'this', their' this' is the outermost 'fn' function is' this'. In normal function 'function', we can call the 'arguments' object to get the actual values of the arguments passed in, but that is not the case in arrow functions. ```js const fn = () => { console.log(arguments); } fn(1, 2); // Uncaught ReferenceError: arguments is not defined function fn() { setTimeout(() => { console.log(arguments); }, 0); } fn(1, 2); // [1, 2] [arguments] : (fn); // [1, 2] : (fn); [arguments] : (fn); As a result, you can't use 'arguments' in arrow functions, and you can't use' caller 'or' callee 'as well. While we can't get arguments from 'arguments', we can use the rest operator ('... ') to achieve this goal. ```js const fn = (... args) => { console.log(args); } fn(1, 2); // [1, 2] (5) support nested js const pipeline = (... funcs) => val => funcs.reduce((a, b => b(a)), val); const plus1 = a => a + 1; const mult2 = a => a * 2; const addThenMult = pipeline(plus1, mult2); addThenMult(5); / / 12 ` ` `Copy the code
Scenarios where arrow functions are not applicable
'this` ```js const Person = {name: 'Kimmy', age: 20, doSomething: () => {this.age++; }}; The person.dosomething () method is an arrow function. When you call Person.dosomething (), if it is a normal function, the 'this' inside the method points to Person. If you write the arrow function like the one above, the' this' points to a global object. (2) the arrow function does not have its own 'this', so it cannot use the arrow function as a constructor. (3) The arrow function does not have its own' this'. Arrow functions cannot also be called through the 'new' operator. Function Person(name) {this.name = name; } let p = new Person('Kimmy'); Let Person = (name) => {this.name = name; } let p = new Person('Kimmy'); // Uncaught TypeError: Person is not a constructor (2).js let a = () => 1; function b() { return 2; } a.prototype // undefined b.prototype // {constructor: ƒ} ' 'when adding the prototype function to the constructor, if the arrow function is used, the' this' in it will point to the global scope 'window' rather than to the constructor, and therefore the constructor itself and instance attributes will not be accessed. This loses its meaning as a prototype function.Copy the code
Reference Documents:
Extension of a function