I am small and live in Wuhan, do two years of new media, ready to use 6 months time to switch to the front end of the industry.
Lesson Objective for today
Yesterday we learned Function data structure based on search. Today is mainly based on search to learn function arrow functions, another day for learning, come on, small and !!!!
Basic instructions
ES6 allows functions to be defined using arrows (=>). Arrow function expressions have a much cleaner syntax than function expressions and don’t have their own this, arguments, super, or new.target. These function expressions are more suitable for places where anonymous functions are needed, and they cannot be used as constructors.
grammar
Basic grammar
(param1, param2,... , paramN) => { statements }/ / is equivalent to
/ / function (param1, param2,... , paramN){ return {statements}; }
(param1, param2,... , paramN) => expression/ / is equivalent to / / function (param1, param2,... , paramN){ return expression; } // Parentheses are optional when there's only one parameter name: // Parentheses are optional when there is only one argument (singleParam) => { statements } singleParam => { statements } / / is equivalent to // function(singleParam){ return expression; } // The parameter list for a function with no parameters should be written with a pair of parentheses. // Functions with no arguments should be written in parentheses. () => { statements } Copy the code
Advanced grammar
// Parenthesize the body of function to return an object literal expression:
// The bracketed function body returns an object literal expression:
params => ({foo: bar})
// Rest parameters and default parameters are supported
// Support remaining parameters and default parameters (param1, param2, ... rest) => { statements }(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements } // Destructuring within the parameter list is also supported Argument list deconstruction is also supported const f = ([a, b] = [1.2], {x: c} = {x: a + b}) = > a + b + c; f(); / / 6 ` ` ` 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.
const sum = (num1, num2) = > { return num1 + num2; }
Copy the code
This paragraph appears a number of new terms, residual parameters and default parameters, deconstruction, feel some do not understand ~~~~
Arrow function variable scope
Variables defined within the arrow function and their scope
General internal variable
//
const greeting_1 = (a)= > {let now = new Date(a);return ("Good" + ((now.getHours() > 17)?" evening." : " day.")); } console.log(greeting_1()); //"Good evening."
console.log(now); // ReferenceError: Now is not defined in the let scope of the standard
Copy the code
parameter
Variables defined in parentheses are local variables (default parameters)
const greeting_2 = (now=new Date()) = > "Good" + (now.getHours() > 17 ? " evening." : " day.");
console.log(greeting_2()); //"Good evening."
console.log(now); // ReferenceError: now is not defined
Copy the code
The body of a function defines variables
Variables defined by {} inside functions that do not use var are global variables
const greeting_3 = (a)= > {now = new Date(a);return ("Good" + ((now.getHours() > 17)?" evening." : " day.")); } console.log(greeting_3()); //"Good evening."
console.log(now); // Wed Apr 24 2019 23:02:07 GMT+0800
Copy the code
Variables defined with const in the body of a function {} are local variables
const greeting_4 = (a)= > {const now = new Date(a);return ("Good" + ((now.getHours() > 17)?" evening." : " day.")); } console.log(greeting_4()); //"Good evening."
console.log(now); // ReferenceError: now is not defined
Copy the code
Main problem solving
Visual optimization
The no-argument arrow function is visually easy to analyze
setTimeout( (a)= > {
console.log('I happen sooner');
setTimeout( (a)= > {
// deeper code
console.log('I happen later');
}, 1); }, 1); Copy the code
Shorter function
const elements = [
'Hydrogen'. 'Helium'. 'Lithium'. 'Beryllium'
]; console.log(elements.map(function(element) { return element.length; })); // [8, 6, 7, 9] // The normal function above can be rewritten as the arrow function below console.log(elements.map((element) = > { return element.length; })); // [8, 6, 7, 9] // If the arrow function has only one argument, omit the parentheses for the argument console.log(elements.map(element= > { return element.length; })); // [8, 6, 7, 9] // When the body of an arrow function has only one 'return' statement, you can omit the 'return' keyword and the curly braces of the method body console.log(elements.map(element= > element.length)); // [8, 6, 7, 9] // In this case, since we only need the 'length' attribute, we can use parameter deconstruction // Note that string 'length' is the name of the attribute we want to obtain, while 'lengthFooBArX' is just a variable name, // Can be replaced with any valid variable name console.log(elements.map(({ "length": lengthFooBArX }) = > lengthFooBArX)); // [8, 6, 7, 9] Copy the code
This is not binding
Before the arrow function, each newly defined function has its own this value (a new object in the case of a constructor, undefined in a strictly modal function call, the underlying object if the function is called as an object method, etc.). This turns out to be a boring object-oriented style of programming.
function Person() {
// The Person() constructor defines' this' as its own instance.
this.age = 0;
setInterval(function growUp() {
// In non-strict mode, growUp() defines' this' as a global object, // Not the same as' this' defined in the Person() constructor. this.age++; }, 1000); } const p = new Person(); console.log(p);// Person {age: 0} Copy the code
In ECMAScript 3/5, this can be solved by assigning the value to a closed variable.
function Person() {
const that = this;
that.age = 0;
setInterval(function growUp() {
// The callback refers to the 'that' variable, whose value is the expected object. that.age++; }, 1000); } Copy the code
Alternatively, you can create a binding function that passes the pre-allocated this value to the binding's target function (the growUp() function in the above example).
The arrow function does not create its own this; it only inherits this from the upper level of its scope chain. Therefore, in the following code, the value of this in the function passed to setInterval is the same as that in the enclosing function:
function Person(){
this.age = 0;
setInterval((a)= > {
this.age++; / / | this | to p instance correctly
}, 1000); } const p = new Person(); Copy the code
Do not bind the arguments
Arrow functions do not bind Arguments objects. Thus, arguments in this example simply refers to arguments in a closed scope:
const arguments = [1.2.3];
const arr = (a)= > arguments[0];
console.log(arr()); / / 1
function foo(n) { const f = (a)= > arguments[0] + n; Arguments [0] is n return f(); } console.log(foo(1)); / / 2 Copy the code
In most cases, using residual arguments is a better choice than using arguments objects.
function foo(arg) {
const f = (. args) = > args[0];
return f(arg);
}
console.log(foo(1)); / / 1
function foo(arg1,arg2) { const f = (. args) = > args[1]; return f(arg1,arg2); } console.log(foo(1.2)); / / 2 Copy the code
Matters needing attention
Methods the function
Arrow function expressions are most appropriate for non-method functions. What happens when you try to use them as methods.
'use strict';
const obj = {
i: 10. b: (a)= > console.log(this.i, this),
c: function() {
console.log(this.i,this) } } console.log(obj.b()); // undefined Window {ƒ : ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, } // undefined console.log(obj.c()); // 10 {I: ƒ, b: ƒ, c: ƒ} // undefined Copy the code
The arrow function does not define the this binding.
Object.defineProperty()
Examples involving Object.defineProperty()
'use strict';
const obj = {
a: 10
};
Object.defineProperty(obj, "b", { get: (a)= > { console.log(this.a, typeof this.a, this); return this.a+10; // NaN // represents the global object 'Window', so 'this.a' returns 'undefined' } }); console.log(obj.b); ƒ : ƒ, focus: ƒ, close: ƒ, frames: Window,... } Copy the code
New operator
Arrow functions cannot be used as constructors; using them with new throws an error.
const Foo = (a)= > {};
const foo = new Foo(); // TypeError: Foo is not a constructor
Copy the code
The prototype property
Arrow functions have no prototype attribute.
const Foo = (a)= > {};
console.log(Foo.prototype); // undefined
Copy the code
yield
The yield keyword usually cannot be used in arrow functions (unless nested within an allowed function). Therefore, arrow functions cannot be used as generators.
The return value is an object literal
Remember that the simple syntax of params => {object:literal} for returning object literals does not work.
Because curly braces are interpreted as blocks of code, if an arrow function returns an object directly, it must enclose parentheses around the object literal or an error will be reported.
/ / an error
// let getTempItem = id => { id: id, name: "Temp" };
// No error is reported but no specified return value is obtained
let getTempItem_1 = id= > { id: id };
// Returns the specified value without an error let getTempItem_2 = id= > ({ id: id, name: "Temp" }); console.log(getTempItem_1(123));// undefined console.log(getTempItem_2(12));// {id: 12, name: "Temp"} Copy the code
In the above code getTempItem_1, the original intent was to return an object {id: id}, but because the engine thought braces were code blocks, it executed a statement id: id.
In this case, id can be interpreted as the label of the statement, so the actual statement executed is ID; , then the function ends with no return value.
Omit braces
If the arrow function has only one line and does not return a value, use the following notation instead of curly braces.
let fn = (a)= > void doesNotReturn();
Copy the code
A newline
Arrow functions cannot break lines between arguments and arrows.
const func = (a)
= > 1;
// SyntaxError: expected expression, got '=>'
Copy the code
Parse order
Although the arrows in arrow functions are not operators, arrow functions have special [Operator Precedence] [operator-precedence] parsing rules that are different from regular functions.
let callback;
callback = callback || function() {}; // ok
callback = callback || (a)= > {};
// SyntaxError: invalid arrow-function arguments callback = callback || (() = > {}); // ok Copy the code
The body of the function
Arrow functions can have a shorthand or common block.
In a shorthand, only one expression is required, with an implicit return value attached. In a block, an explicit return statement must be used.
var func = x= > x * x;
// The shorthand function omits return
var func = (x, y) = > { return x + y; };
// Generally write explicit return values
Copy the code
Relationship to strict patterns
Since this is lexical, rules related to this are ignored in strict mode.
function Person() {
this.age = 0;
const closure = "123"
setInterval(function growUp() {
this.age++;
console.log(closure); }, 1000); } const p = new Person(); function PersonX() { 'use strict' this.age = 0; const closure = "123" setInterval((a)= >{ this.age++; console.log(closure); }, 1000); } const px = new PersonX(); console.log(px);// PersonX {age: 0} Copy the code
The other rules of strict mode remain the same.
call & apply
Since arrow functions do not have their own this pointer, when a function is called through call() or apply(), only arguments (not this) are passed, and their first argument is ignored. (The same is true for bind.)
const adder = {
base : 1. add : function(a) {
const f = v= > v + this.base;
return f(a);
}, addThruCall: function(a) { const f = v= > v + this.base; const b = { base : 2 }; return f.call(b, a); } }; console.log(adder.add(1)); 2 / / output console.log(adder.addThruCall(1)); // Still outputs 2 (instead of 3) Copy the code
Use case
Simple basic function
The arrow function makes the presentation more concise.
const isEven = n= > n % 2= = =0;
const square = n= > n * n;
Copy the code
The above code defines two simple utility functions in just two lines. If you didn't use the arrow function, it would take up multiple lines, and it wouldn't be as bold as it is now.
Concise callback function
One use of the arrow function is to simplify the callback function.
// The normal function
[1.2.3].map(function (x) {
return x * x;
});
// arrow function [1.2.3].map(x= > x * x); Copy the code
Here's another example
// The normal function
const result = values.sort(function (a, b) {
return a - b;
});
// arrow function const result = values.sort((a, b) = > a - b); Copy the code
Array related
Convenient arrays reduce,filter, and Map;
// Easy array filtering, mapping, ...
const arr = [5.6.13.0.1.18.23];
const sum = arr.reduce((a, b) = > a + b);
console.log(sum); / / 66 const even = arr.filter(v= > v % 2= =0); console.log(even); / / [18] 6, 0, const double = arr.map(v= > v * 2); console.log(double); // [10, 12, 26, 0, 2, 36, 46] Copy the code
IIFE
// Empty arrow function returns undefined
const empty = (a)= > {};
console.log((() = > 'foobar') ());// foobar
// (this is an immediate function expression, see the 'IIFE' glossary) Copy the code
Ternary operator
Arrow functions can also use conditional (ternary) operators
const simple = a= > a > 15 ? 15 : a;
console.log(simple(16)); / / 15
console.log(simple(10)); / / 10
let max = (a, b) = > a > b ? a : b;
console.log(max(4.5));/ / 5 Copy the code
Refer to the website
- arrow function: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
- Church_encoding: https://en.wikipedia.org/wiki/Church_encoding
- combinators: https://en.wikipedia.org/wiki/Fixed-point_combinator#Strict_fixed_point_combinator
- how-to-use-arrow: https://github.com/getify/You-Dont-Know-JS/blob/master/es6%20%26%20beyond/fig1.png
- Operator-Precedence: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
Summary of today's lesson
Today the mood
Today is mainly based on the search to learn the basic function arrow function, feel the arrow function is used, the main content is much simpler, and then understand the remaining parameters, default parameters and deconstruction, after a more detailed understanding, I hope to learn more tomorrow ~~~~
This article is formatted using MDNICE