当前位置:网站首页>Ecmascript6 introduction and environment construction

Ecmascript6 introduction and environment construction

2022-07-05 08:48:00 Front end Jiang Taigong

1、ES6 brief introduction

1.1、 What is? ES6

ECMAScript 6.0( hereinafter referred to as ES6) yes JavaScript The next generation standard of language , Already in 2015 year 6 It was officially released in April . Its goal , Is making JavaScript Language can be used to write complex large applications , Become an enterprise development language .

1.2、ECMAScript and JavaScript The relationship between

A common problem is ,ECMAScript and JavaScript What is the relationship ?

We need to be clear about this problem , Need to look back on history .1996 year 11 month ,JavaScript Creator Netscape company , It was decided that JavaScript Submit to standardization organization ECMA, I hope this language can become an international standard . The following year ,ECMA Release 262 Standard Document No (ECMA-262) The first edition of , It defines the standard of browser scripting language , And call this language ECMAScript, This version is 1.0 edition . The standard has been for JavaScript Language made , But it's not called JavaScript, There are two reasons . One is the trademark ,Java yes Sun The company's trademark , According to the license agreement , Only Netscape Companies can use... Legally JavaScript The name , And JavaScript It has also been Netscape The company is registered as a trademark . Second, the makers who want to embody the language are ECMA, No Netscape, This is conducive to ensuring the openness and neutrality of the language . therefore ,ECMAScript and JavaScript The relationship is , The former is the latter's specification , The latter is an implementation of the former ( additional ECMAScript Dialects and JScript and ActionScript). Everyday occasions , These two words are interchangeable .

1.3、 Why study ES6?

This question can be changed into a question , It's the end of learning es6 What kind of convenience will it bring to our development ?chrome explain javascript Our engine is called V8, One person put V8 The engine is transferred to the server , So the server can also write javascript, This kind of server-side operation js Language , Namely Node.js.Node.js Once published , Its superior performance shows , Many are based on nodejs Of web The framework also came into being ,express It's one of them , What follows is the whole stack MEAN mogoDB,Express,Vue.js,Node.js Development ,javaScript More and more people use web Every corner of the field ,js More and more things can be done .Babel Is a widely used ES6 Transcoder , Can be ES6 The code changes to ES5 Code , In order to execute... In the existing environment . It means , You can use it. ES6 How to write a program , And don't worry about whether the existing environment supports .nodejs It is a development trend ,Vue.js This front-end framework is a development trend ,ES6 It is also a trend to be widely used . At present, some front-end frameworks are in use ES6 grammar , for example Vue、React、D3 wait , therefore ES6 It is also the basis for learning a good front-end framework .

2、ES6 Environment building

Because some lower versions of browsers do not support ES6 The grammar of , So without using a framework , Need to put ES6 Syntax to ES5 grammar .

2.1、 Preparation

Create a project first , There are two folders in the project ,src and dist, One html file

src: Will be written ES6 Of js Put the files in this folder ( Here is index.js file ) dist: Will pass through Babel Compiled into ES5 Of js Put the file in this file ( Here is index.js file ) html: Be careful : take dist The compiled file in is imported into HTML In file , instead of src Medium js file

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<script src="./dist/index.js"></script>
</head>
<body>
	Hello ES6
</body>
</html>

2.2、ES6 Environment building

First step

stay src Under the table of contents , newly build index.js file . This file is very simple , We only make one a Declaration of variables , And use console.log() Print out .

let a = 1;
console.log(a);

The second step

Initialize the project in the root directory of the project and generate package.json file ( You can modify it according to your own needs )

cnpm init -y
{
    "name": "es6",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
     },
    "keywords": [],
    "author": "",
    "license": "ISC"
}

The third step

install Babel plug-in unit ( take ES6 Syntax to ES5)

cnpm install -g babel-cli

Step four

Of course, it can't be converted normally yet , It also needs to be installed ES5 A package required

cnpm install --save-dev babel-preset-es2015 babel-cli 
##  After installation ,package.json There will be changes 
{
    "name": "es6",
     "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-preset-es2015": "^6.24.1"
    }
}

Step five :

Add a .babelrc file , And add content

{
    "presets":[
        "es2015"
    ],
    "plugins": []
}

stay windows Create... In the system .babelrc Method of file

Method 1 : The root directory , establish “.babelrc.” Just a file name !( There are two points before and after )

Method 2 :cmd Go to the root directory , Input “type null>.babelrc”, You can enter. !

Step six :

After installation, we can convert by command

babel src/index.js -o dist/index.js

Step seven :

Commands can be simplified (package.json To configure )

"scripts": {
    "test": "echo "Error: no test specified" && exit 1"
},

It is amended as follows :

{
  	"name": "es6",
  	"version": "1.0.0",
  	"description": "",
  	"main": "index.js",
  	"scripts": {
        "test": "babel src/index.js -o dist/index.js"
  	},
  	"keywords": [],
  	"author": "",
  	"license": "ISC",
  	"devDependencies": {
		"babel-cli": "^6.26.0",
		"babel-preset-es2015": "^6.24.1"
  	}
}

Then we can escape the code with the following command :

npm run test

3、let And const

ES2015(ES6) Two important ones have been added JavaScript keyword : let and const.

let Declared variables are only in let The command is valid in the code block ,const Declare a read-only constant , Once declared , You can't change the value of a constant .

3.1、let command

let The command has the following characteristics :

(1) Valid in code block

ES2015(ES6) Two important ones have been added JavaScript keyword : let and const.let Declared variables are only in let The command is valid in the code block ,const Declare a read-only constant , Once declared , You can't change the value of a constant .

{
    let a = 1;
    var b = 2;
    console.log(a);// Output 1
    console.log(b);// Output 2
}
console.log(a);// Report errors  ReferenceError: a is not defined
console.log(b);// Output 2

(2) Cannot repeat declaration

let It can only be declared once var It can be stated many times :

let a = 1;
let a = 2;// Report errors  Identifier 'a' has already been declared
var b = 3;
var b = 4;
console.log(a);
console.log(b);// Output 4

for The cycle counter is very suitable for use let

for (var i = 0; i < 10; i++) {
  setTimeout(function(){
    console.log(i);
  })
}
//  Output ten  10
for (let j = 0; j < 10; j++) {
  setTimeout(function(){
    console.log(j);
  })
}
//  Output  0123456789

Variable i Yes, it is var Declarative , Valid globally , So there is only one variable in the global i, Every time you cycle ,setTimeout In the timer i Refers to global variables i , And the ten in the cycle setTimeout Is executed after the end of the loop , So at this time i All are 10.

Variable j Yes, it is let Declarative , Current j Only valid in this cycle , Every cycle of j It's actually a new variable , therefore setTimeout In the timer j It's actually a different variable , That is, the final output 12345.( If the variables in each loop j It's all restated , How to know the value of the previous loop ? This is because JavaScript The internal loop will remember the previous value ).

(3) No variable promotion

let No variable promotion ,var Variable promotion :

console.log(a);  //ReferenceError: a is not defined
let a = "apple";

console.log(b);  //undefined
var b = "banana";

Variable b use var Declare that there is a variable Promotion , So when the script starts running ,b It already exists , But it hasn't been assigned yet , So it will output undefined. Variable a use let Declare that there is no variable promotion , In the declaration of variables a Before ,a non-existent , So there's an error .

(4) Temporary dead zone

As long as there is... In the block level scope let command , The variables it declares are “ binding ”(binding) This area , No longer affected by the outside .

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

In the above code , There are global variables tmp, But in block level scope let A local variable is declared tmp, Causes the latter to bind the block level scope , So in let Before declaring variables , Yes tmp The assignment will report an error .

ES6 Make it clear , If a block exists let and const command , Variables declared by this block for these commands , Closed scopes have been formed from the beginning . Always use these variables before declaring them , You're going to report a mistake .

All in all , In code block , Use let Before a command declares a variable , This variable is not available . This is in grammar , be called “ Temporary dead zone ”(temporal dead zone, abbreviation TDZ).

if (true) {
  // TDZ Start 
  tmp = 'abc'; // ReferenceError
  console.log(tmp); // ReferenceError

  let tmp; // TDZ end 
  console.log(tmp); // undefined

  tmp = 123;
  console.log(tmp); // 123
}

In the above code , stay let Command declaration variable tmp Before , All variables tmp Of “ dead zone ”.

“ Temporary dead zone ” Also means that typeof It's no longer a 100% safe operation .

typeof x; // ReferenceError
let x;

in addition , The following code will also report an error , And var Different behavior .

//  Don't complain 
var x = x;

//  Report errors 
let x = x;
// ReferenceError: x is not defined

The above code reports an error , It's also because of the temporary dead zone . Use let When variables are declared , As long as the variable is used before the declaration is complete , You're going to report a mistake . This is the case with the above line , In variables x Before the execution of the declaration statement is completed , Just go and get it x Value , Result in an error ”x Undefined “.

ES6 Temporary deadband and let、const Statement does not have variable promotion , Mainly to reduce runtime errors , Prevent using this variable before it is declared , Which leads to unexpected behavior . Such a mistake lies in ES5 It's very common , Now there's this rule , It's easy to avoid such mistakes .

All in all , The essence of a temporary dead zone is , As soon as you enter the current scope , The variable to be used already exists , But not available , Only wait until the line that declares the variable appears , To get and use this variable .

3.2、const command

const Declare a read-only variable , No change is allowed after the declaration . signify , Once declared must be initialized , Otherwise, an error will be reported .

Basic usage :

const PI = "3.1415926";
PI  // 3.1415926

const MY_AGE;  //  Report errors  SyntaxError: Missing initializer in const declaration

const Declared variable must not change value , It means ,const Once a variable is declared , It must be initialized immediately , It cannot be left for later assignment .

const foo;
//  Report errors  SyntaxError: Missing initializer in const declaration

The code above indicates , about const Come on , Only declare no assignment , You're going to report a mistake .const The scope of let The same command : Valid only in the block level scope where the declaration is located .

if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined

const The constant declared by the command is also not promoted , There is also a temporary dead zone , Can only be used after the declared position .

if (true) {
  console.log(MAX); // ReferenceError
  const MAX = 5;
}

The above code is constant MAX Call... Before declaration , The result is wrong .const Declared constant , Also with the let Same non repeatable statement .

var message = "Hello!";
let age = 25;

//  The following two lines will be wrong 
const message = "Goodbye!";
const age = 30;

Temporary dead zone :

var PI = "a";
if(true){
  console.log(PI);  // Report errors  ReferenceError: PI is not defined
  const PI = "3.1415926";
}

ES6 Make it clear , If there is... In the code block let perhaps const, Code blocks form a closed scope for the variables declared by these commands from the beginning of the block . Within code block , In the declaration of variables PI Using it before will report an error .

Pay attention to the point const How to make variables not allowed to change after declaration initialization ? Actually const In fact, the guarantee is not that the value of the variable remains unchanged , It ensures that the data stored in the memory address pointed to by the variable is not allowed to be changed . here , You may have thought of , Simple types and compound types hold values in different ways . Yes , For simple types ( The number number、 character string string 、 Boolean value boolean), The value is stored at the memory address that the variable points to , therefore const Declared simple type variables are equivalent to constants . And complex types ( object object, Array array, function function), The memory address that the variable points to is actually a pointer to the actual data , therefore const It can only guarantee that the pointer is fixed , As for the data structure that the pointer points to, it can't be controlled if it doesn't change , So use const Be careful when declaring complex type objects .

4、ES6 Deconstruct assignment

4.1、 Overview of deconstruction assignment

Deconstructing assignment is an extension of assignment operator .

It is a method of... For arrays or objects Pattern matching , And then assign values to the variables . Simple and easy to read in code writing , The meaning is clearer ; It is also convenient to obtain data fields in complex objects .

4.2、 Deconstruction model

ES6 Allow to follow certain mode , Extract values from arrays and objects , Assign values to variables , This is known as deconstruction (Destructuring).

In Deconstruction , There are two parts to participate in :

The source of deconstruction , Deconstruct the right part of the assignment expression ;

Deconstruction goal , Deconstruct the left part of the assignment expression ;

stay ES5 in , Assigning a value to a variable can only directly specify the value of the variable :

let a = 1;
let b = 2;

stay ES6 in , Variable assignment is allowed to be written as :

let [a,b,c] = [1,2,3];
console.log(a); //  Output 1
console.log(b); //  Output 2
console.log(c); //  Output 3

Face code indicates , You can extract values from arrays , According to the corresponding position , Assign a value to a variable .

Essentially , This is the way it's written “ Pattern matching ”, As long as the patterns on both sides of the equal sign are the same , The variable on the left is given the corresponding value .

4.3、 Deconstruction and assignment of arrays

Basic usage

let [a, b, c] = [1, 2, 3];
// a = 1
// b = 2
// c = 3

Can be nested

let [a, b, c] = [1, 2, 3];
// a = 1
// b = 2
// c = 3

Negligible

let [a, , b] = [1, 2, 3];
// a = 1
// b = 3

Incomplete deconstruction

let [a = 1, b] = []; // a = 1, b = undefined

If deconstruction is not successful , The value of the variable is equal to undefined.

let [foo] = [];
let [bar, foo] = [1];

In both cases, deconstruction is unsuccessful ,foo Will be equal to undefined.

Another situation is incomplete deconstruction , The pattern to the left of the equal sign , Match only a part of the array to the right of the equal sign . In this case , Deconstruction can still succeed .

let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

The above two examples , All belong to incomplete deconstruction , But it works .

If the right side of the equals sign is not an array ( Or, strictly speaking , Not ergodic structures ), Then there will be an error .

//  Report errors 
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

All the above statements will report errors , Because the value to the right of the equal sign , Or you don't have Iterator Interface ( The first five expressions ), Or not in itself Iterator Interface ( The last expression ).

Remainder operator

let [a, ...b] = [1, 2, 3];
//a = 1
//b = [2, 3]

character string

In the deconstruction of arrays , If the object of deconstruction is an ergodic object , Can be deconstructed and assigned . The traversable object implements Iterator Interface data .

let [a, b, c, d, e] = 'hello';
// a = 'h'
// b = 'e'
// c = 'l'
// d = 'l'
// e = 'o'

Deconstruct default

Deconstruction assignments allow you to specify the default value .

let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'

When deconstruction patterns have matching results , And the matching result is undefined when , The default value is triggered as the return result .

let [a = 2] = [undefined]; // a = 2

Be careful ,ES6 The strict equality operator is used internally (===), Judge whether a position has value . therefore , Only when an array member is strictly equal to undefined, The default value will take effect .

let [x = 1] = [undefined];
x // 1

let [x = 1] = [null];
x // null

In the above code , If an array member is null, The default value will not take effect , because null Not strictly equal to undefined.

If the default value is an expression , So this expression is evaluated lazily , Only when it is used , To evaluate .

function f() {
  console.log('aaa');
}

let [x = f()] = [1];

In the above code , because x Can get the value , So the function f Not at all . The above code is actually equivalent to the following code .

let x;
if ([1][0] === undefined) {
  x = f();
} else {
  x = [1][0];
}

The default value can refer to other variables assigned by deconstruction , But the variable must have declared .

let [a = 3, b = a] = []; // a = 3, b = 3
let [a = 3, b = a] = [1];// a = 1, b = 1
let [a = 3, b = a] = [1, 2]; // a = 1, b = 2
let [a = b, b = 1] = []; // ReferenceError: y is not defined

Above code explanation :

  • a And b The matching result is undefined , Trigger default :a = 3; b = a =3;
  • a Normal deconstruction assignment , Matching results :a = 1,b Matching results undefined , Trigger default :b = a =1;
  • a And b Normal deconstruction assignment , Matching results :a = 1,b = 2;
  • The last expression above will report an error , Because x use y When making default value ,y There is no statement yet .

4.4、 Object's deconstruction assignment

(1) Basic usage

Deconstruction can be used not only for arrays , Can also be used for objects .

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

An important difference between object deconstruction and array . The elements of an array are ordered , The value of a variable depends on its position ; The properties of an object have no order , Variable must have the same name as property , To get the right value .

let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined

The first example of the above code , The order of the two variables to the left of the equal sign , The order of the two attributes with the same name to the right of the equal sign is inconsistent , But it has no effect on the value . In the second example, the variable does not have a corresponding property of the same name , Resulting in a loss of value , In the end, it's equal to undefined.

If deconstruction fails , The value of the variable is equal to undefined.

let {foo} = {bar: 'baz'};
foo // undefined

In the above code , The object to the right of the equal sign has no foo attribute , So the variable foo Can 't get value , So it's equal to undefined.

Object's deconstruction assignment , It's easy to put existing object methods , Assign to a variable .

//  Patients with a 
let { log, sin, cos } = Math;

//  Example 2 
const { log } = console;
log('hello') // hello

Example 1 of the above code will Math The logarithm of the object 、 sine 、 Cosine three ways , Assign a value to the corresponding variable , It will be much more convenient to use . Example 2 will console.log Assign values to the log Variable .

If the variable name is not the same as the property name , It must be written as follows .

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"

let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'

This actually means , The deconstruction assignment of an object is short for the following form .

let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };

in other words , The internal mechanism of object's Deconstruction and assignment , First find the attribute with the same name , And then assign it to the corresponding variable . What is really assigned is the latter , Not the former .

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
foo // error: foo is not defined

In the above code ,foo It's a matching pattern ,baz Is the variable . What's really assigned is the variable baz, Not the pattern foo.

(2) Deconstruction assignment of nested objects

Same as array , Deconstruction can also be used for nested objects .

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"

Be careful , At this time p Is the mode , Is not a variable , So it will not be assigned . If p It's also assigned as a variable , It can be written as follows .

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]

Here's another example .

4.5、 Considerations for deconstruction assignment

(1) If you want to use a declared variable to deconstruct an assignment , You have to be very careful .

//  The wrong way to write 
let x;
{x} = {x: 1};
// SyntaxError: syntax error

The writing of the above code will report an error , because JavaScript The engine will {x} Understand as a block of code , So there are grammatical errors . Just don't start the line with braces , avoid JavaScript Interpret it as a code block , To solve this problem .

//  Correct writing 
let x;
({x} = {x: 1});

The above code will deconstruct the entire assignment statement , Put it in a parenthesis , Then it can be carried out correctly . On the relationship between parentheses and deconstruction assignment , See below .

(2) Deconstruction assignment allows the pattern to the left of the equal sign , Don't put any variable names . therefore , You can write very strange assignment expressions .

({} = [true, false]);
({} = 'abc');
({} = []);

The above expression is meaningless , But grammar is legal , It can be executed .

(3) Because arrays are special objects in nature , Therefore, you can deconstruct the properties of an array .

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3

The above code deconstructs the array . Array arr Of 0 The value of the key is 1,[arr.length - 1] Namely 2 key , The corresponding value is 3. Square brackets, this way of writing , Belong to “ Property name expression ”.

4.6、 The purpose of deconstruction assignment

The deconstruction of variables has many uses .

(1) Exchange the values of variables

let x = 1;
let y = 2;

[x, y] = [y, x];

The above code exchanges variables x and y Value , This way of writing is not only simple , And it's easy to read , The semantics are very clear .

(2) Return multiple values from function

Function can only return one value , If you want to return multiple values , They can only be returned in arrays or objects . With deconstruction assignment , It's very convenient to take out these values .

//  Returns an array 

function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

//  Return an object 

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

(3) Definition of function parameters

Deconstruction assignment makes it easy to map a set of parameters to a variable name .

//  Parameters are a set of ordered values 
function f([x, y, z]) { ... }
f([1, 2, 3]);

//  Parameter is a set of unordered values 
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

(4) extract JSON data

Deconstruct assignment pairs to extract JSON Data in object , Especially useful .

let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]

The above code can be extracted quickly JSON The value of the data .

(5) The default value of the function parameter

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
} = {}) {
  // ... do stuff
};

Specifies the default value of the parameter , Avoid writing inside the function body var foo = config.foo || ‘default foo’; Such a statement .

(6) Traverse Map structure

Any deployment of Iterator Object of the interface , Both can be used. for…of Loop traversal .Map Structure native support Iterator Interface , With the deconstruction of variables , Getting the key name and value is very convenient .

const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world

If you just want to get the key name , Or just want to get the key value , It can be written as follows .

//  Get key name 
for (let [key] of map) {
  // ...
}

//  Get key value 
for (let [,value] of map) {
  // ...
}

(7) How to specify the input module

When loading modules , Often you need to specify which methods to input . Deconstructing assignment makes the input statement very clear .

const { SourceMapConsumer, SourceNode } = require("source-map");

5、 character string 、 function 、 Array 、 Object extension

5.1、 Template string

Conventional JavaScript Language , Output templates are usually written like this ( The following is used jQuery Methods ).

$('#result').append(
  'There are <b>' + basket.count + '</b> ' +
  'items in your basket, ' +
  '<em>' + basket.onSale +
  '</em> are on sale!'
);

The above writing method is rather cumbersome and inconvenient ,ES6 Template string is introduced to solve this problem .

$('#result').append(`
  There are <b>${basket.count}</b> items
   in your basket, <em>${basket.onSale}</em>
  are on sale!
`);

Template string (template string) It's an enhanced string , Use back quotes (`) identification . It can be used as a normal string , It can also be used to define multiline strings , Or embed variables in strings .

//  Normal string 
`In JavaScript '\n' is a line-feed.`

//  Multiline string 
`In JavaScript this is
 not legal.`

console.log(`string text line 1
string text line 2`);

//  Embed variables in string 
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

The template string in the above code , It's all in back quotes .

Escape symbol

If you need to use backquotes in the template string , Then use the backslash to escape .

let greeting = `\`Yo\` World!`;

Multiline string

If you use template strings to represent multiline strings , All spaces and indents are retained in the output .

$('#list').html(`
<ul>
  <li>first</li>
  <li>second</li>
</ul>
`);

In the above code , Spaces and line breaks for all Template Strings , It's all reserved , such as <ul> There will be a new line in front of the label . If you don't want this line break , have access to trim Ways to eliminate it .

$('#list').html(`
<ul>
  <li>first</li>
  <li>second</li>
</ul>
`.trim());

Insert the variable

Embed variables in the template string , You need to write the variable name in ${} In .

function authorize(user, action) {
  if (!user.hasPrivilege(action)) {
    throw new Error(
      //  The traditional way of writing is 
      // 'User '
      // + user.name
      // + ' is not authorized to do '
      // + action
      // + '.'
      `User ${user.name} is not authorized to do ${action}.`);
  }
}

Insert expression

You can put any... Inside the braces JavaScript expression , It can be calculated , And reference object properties .

let x = 1;
let y = 2;

`${x} + ${y} = ${x + y}`
// "1 + 2 = 3"

`${x} + ${y * 2} = ${x + y * 2}`
// "1 + 4 = 5"

let obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// "3"

Call function

Functions can also be called in the template string .

function fn() {
  return "Hello World";
}

`foo ${fn()} bar`
// foo Hello World bar

If the value in braces is not a string , Convert to string according to general rules . such as , In braces is an object , Will call the object's by default toString Method .

If the variables in the template string are not declared , Will be an error .

//  Variable place No statement 
let msg = `Hello, ${place}`;
//  Report errors 

Because the template string is inside braces , Is to perform JavaScript Code , So if there's a string inside curly braces , Will output as is .

`Hello ${'World'}`
// "Hello World"

Pay attention to the point

Newlines and spaces in the template string are preserved

innerHtml = `<ul>
  <li>menu</li>
  <li>mine</li>
</ul>
`;
console.log(innerHtml);
//  Output 
<ul>
 <li>menu</li>
 <li>mine</li>
</ul>

5.2、 String extension method

(1) Identification of substrings

ES6 Before judging whether the string contains substrings , use indexOf Method ,ES6 A new method for identifying substrings is added .

  • includes(): Returns a Boolean value , Determine if the parameter string is found .
  • startsWith(): Returns a Boolean value , Judge whether the parameter string is in the head of the original string .
  • endsWith(): Returns a Boolean value , Judge whether the parameter string is at the end of the original string .

The above three methods can accept two parameters , String to search for , And optional search start index .

let s = 'Hello world!';

s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true

All three methods support the second parameter , Indicates where to start the search .

let s = 'Hello world!';

s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false

The code above indicates , Use the second parameter n when , endsWith Our behavior is different from the other two methods . It's for the front n Characters , And the other two methods are from n Positions until the end of the string .

Be careful :

  • These three methods only return Boolean values , If you need to know the position of the substring , Still have to use indexOf and lastIndexOf .
  • If these three methods pass in a regular expression instead of a string , Will throw an error . and indexOf and lastIndexOf These two methods , They convert the regular expression to a string and search for it .

(2) Duplicate string

repeat(): Returns a new string , Indicates that the string is repeated a specified number of times .

'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""

If the parameter is a decimal , Will be rounded down .

'na'.repeat(2.9) // "nana"

If repeat The argument to is negative or Infinity , Will report a mistake .

'na'.repeat(Infinity)
// RangeError
'na'.repeat(-1)
// RangeError

however , If the parameter is 0 To -1 Decimal between , Is equivalent to 0, This is because the rounding operation will be performed first .0 To -1 Decimal between , After rounding, it's equal to -0 , repeat Deemed as 0.

'na'.repeat(-0.9) // ""

Parameters NaN Equate to 0.

'na'.repeat(NaN) // ""

If repeat The argument to is a string , Then it will be converted into numbers first .

'na'.repeat('na') // ""
'na'.repeat('3') // "nanana"

(3) String completion

ES2017 The function of string completion length is introduced . If a string is not long enough , Will be completed at the head or tail .

  • padStart: Returns a new string , Represents a parameter string from the header ( left ) Complete the original string .
  • padEnd: Returns a new string , Indicates that a parameter string is used from the end ( On the right side ) Complete the original string .

The above two methods accept two parameters , The first parameter is to specify the minimum length of the generated string , The second parameter is the string used to complete . If the second parameter is not specified , Fill with space by default .

console.log("h".padStart(5,"o"));  // "ooooh"
console.log("h".padEnd(5,"o"));    // "hoooo"
console.log("h".padStart(5));      // "    h"

console.log('x'.padStart(5, 'ab')); // 'ababx'
console.log('x'.padStart(4, 'ab')); // 'abax'

console.log('x'.padEnd(5, 'ab')); // 'xabab'
console.log('x'.padEnd(4, 'ab')); // 'xaba'

In the above code , padStart() and padEnd() Two parameters are accepted , The first parameter is the maximum length of string completion , The second parameter is the string used to complete .

If the specified length is less than or equal to the length of the original string , Return the original string :

console.log("hello".padStart(5,"A"));  // "hello"

If the length of the original string plus the completion string is greater than the specified length , The completion string that exceeds the number of digits is truncated :

console.log("hello".padEnd(10,",world!"));  // "hello,worl"

If you omit the second parameter , By default, space is used to complete the length .

console.log('x'.padStart(4)); // '   x'
console.log('x'.padEnd(4)); // 'x   '

padStart() The common use of is to complete a specified number of digits for a value . The following code is generated 10 Bit numeric string .

console.log('1'.padStart(10, '0')); // "0000000001"
console.log('12'.padStart(10, '0')); // "0000000012"
console.log('123456'.padStart(10, '0')); // "0000123456"

Another use is to prompt for string formats .

console.log('12'.padStart(10, 'YYYY-MM-DD')); // "YYYY-MM-12"
console.log('09-12'.padStart(10, 'YYYY-MM-DD')); // "YYYY-09-12"

(4) Eliminate spaces

ES6 Add... To the string instance trimStart() and trimEnd() These two methods . Their behavior is related to trim() Agreement ,trimStart() Remove the space at the head of the string ,trimEnd() Eliminate trailing spaces . They all return new strings , The original string is not modified .

const s = '  abc  ';

s.trim() // "abc"
s.trimStart() // "abc  "
s.trimEnd() // "  abc"

In the above code ,trimStart() Just eliminate the spaces in the head , Keep trailing spaces .trimEnd() Similar behavior .

Except for the space bar , These two methods are for string headers ( Or the tail ) Of tab key 、 Invisible white space symbols such as line breaks are also valid .

The browser also deploys two additional methods ,trimLeft() yes trimStart() Another name for ,trimRight() yes trimEnd() Another name for .

5.3、 Function extension

(1) The default value is

ES6 Before , You can't directly specify default values for parameters of a function , We can only take a flexible approach .

function log(x, y) {
  y = y || 'World';
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello World

The above code checks the function log Parameters of y There is no assignment , without , The default value is World. The disadvantage of this way of writing is that , If parameters y Assigned a value to , But the corresponding Boolean value is false, Then the assignment has no effect . Like the last line of the code above , Parameters y Equal to null character , The result is changed to the default value .

To avoid this problem , Usually you need to judge the parameters first y Whether it is assigned , without , And then equal to the default value .

if (typeof y === 'undefined') {
  y = 'World';
}

ES6 Allows you to set default values for parameters of a function , That is, it is written directly after the parameter definition .

function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello

You can see ,ES6 Writing ratio ES5 It's a lot simpler , And it's very natural . Here's another example .

function Point(x = 0, y = 0) {
  this.x = x;
  this.y = y;
}

const p = new Point();
p // { x: 0, y: 0 }

In addition to brevity ,ES6 There are two other advantages of writing : First , People who read the code , You can immediately realize which parameters can be omitted , You don't have to look at function bodies or documents ; secondly , Conducive to future code optimization , Even if the future version is in the external interface , Completely remove this parameter , It will not cause the previous code to fail to run .

Parameter variables are declared by default , So it can't be used let or const Once again .

function foo(x = 5) {
  let x = 1; // error
  const x = 2; // error
}

In the above code , Parameter variable x Is declared by default , In the body of a function , Out-of-service let or const Once again , Otherwise, an error will be reported .

When using parameter defaults , Functions cannot have arguments with the same name .

//  Don't complain 
function foo(x, x, y) {
  // ...
}

//  Report errors 
function foo(x, x, y = 1) {
  // ...
}
// SyntaxError: Duplicate parameter name not allowed in this context

in addition , One thing that is easy to ignore is , The default value of the parameter is not passed , Instead, the value of the default value expression is recalculated every time . in other words , The default value of the parameter is inert .

let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101

In the above code , Parameters p The default value of is x + 1. At this time , Every time you call a function foo, Will recalculate x + 1, Not by default p be equal to 100.

(2) Uncertain parameters

Indeterminate parameters are used to represent the number of indeterminate parameters , Form like ,… Variable name , from … Plus a named parameter identifier . Named parameters can only be placed at the end of a parameter group , And there is only one indefinite parameter .

Basic usage

function f(...values){
    console.log(values.length);
}
f(1,2);      //2
f(1,2,3,4);  //4

(3) Arrow function

Arrow functions provide a more concise way to write functions . The basic grammar is :

 Parameters  =>  The body of the function 

Basic usage :

var f = v => v;
// Equivalent to 
var f = function(a){
 return a;
}
f(1);  //1

When an arrow function has no or multiple arguments , Use () Cover up .

var f = (a,b) => a+b;
f(6,2);  //8

When an arrow function body has multiple lines , use {} Wrap it up , Represents a code block , When there is only one line , And when you need to return the results , It can be omitted {} , The results will return automatically .

var f = (a,b) => {
 let result = a+b;
 return result;
}
f(6,2);  // 8

When the arrow function returns an object , To distinguish between code blocks , Use () Wrap objects

//  Report errors 
var f = (id,name) => {id: id, name: name};
f(6,2);  // SyntaxError: Unexpected token :
 
//  Don't complain 
var f = (id,name) => ({id: id, name: name});
f(6,2);  // {id: 6, name: 2}

Be careful : No, this、super、arguments and new.target binding .

var func = () => {
  //  There's nothing in the arrow function  this  object ,
  //  At this time  this  It's outer  this  object , namely  Window 
  console.log(this)
}
func(55)  // Window 
 
var func = () => {    
  console.log(arguments)
}
func(55);  // ReferenceError: arguments is not defined

Arrow in function body this object , Is the object when the function is defined , Instead of the object when using the function .

function fn(){
  setTimeout(()=>{
    //  Definition time ,this  The binding is  fn  Medium  this  object 
    console.log(this.a);
  },0)
}
var a = 20;
// fn  Of  this  The object is  {a: 19}
fn.call({a: 18});  // 18

Can't be used as a constructor , That is, you can't use new command , Otherwise, an error will be reported

5.4、 Extension of arrays

(1) Extension operator

Extension operator (spread) Three points (...). It's like rest Inverse operation of parameter , Convert an array to a comma separated sequence of parameters .

console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5

[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]

This operator is mainly used for function calls .

function push(array, ...items) {
  array.push(...items);
}

function add(x, y) {
  return x + y;
}

const numbers = [4, 38];
add(...numbers) // 42

In the above code ,array.push(...items) and add(...numbers) These two lines , All are function calls , They all use the extension operator . This operator takes an array , Change to parameter sequence .

(2) Application of extension operators

Copy the array

Arrays are composite data types , If you copy directly , Just copied the pointer to the underlying data structure , Instead of cloning a whole new array .

const a1 = [1, 2];
const a2 = a1;

a2[0] = 2;
a1 // [2, 2]

In the above code ,a2 Not at all a1 The clone , It's another pointer to the same data . modify a2, Will lead directly to a1 The change of .

ES5 You can only copy arrays in a flexible way .

const a1 = [1, 2];
const a2 = a1.concat();

a2[0] = 2;
a1 // [1, 2]

In the above code ,a1 Will return a clone of the original array , Revise a2 It won't be right a1 An impact .

Extended operators provide a simple way to copy arrays .

const a1 = [1, 2];
//  Writing a 
const a2 = [...a1];
//  Write two 
const [...a2] = a1;

The above two ways of writing ,a2 All are a1 The clone .

Merge array

The extension operator provides a new way to write array merging .

const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];

// ES5  The merge array of 
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]

// ES6  The merge array of 
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

however , Both methods are shallow copies , You need to pay attention to .

const a1 = [{ foo: 1 }];
const a2 = [{ bar: 2 }];

const a3 = a1.concat(a2);
const a4 = [...a1, ...a2];

a3[0] === a1[0] // true
a4[0] === a1[0] // true

In the above code ,a3 and a4 It's a new array formed by combining two different methods , But their members are all references to the original array members , This is a shallow copy . If you modify the members of the original array , It will be synchronized to the new array .

(3) Of the array instance find() and findIndex()

Of the array instance find Method , To find the first qualified member of the array . Its argument is a callback function , All array members execute the callback function in turn , Until you find out that the first return value is true Members of , Then return to the member . If there are no eligible members , Then return to undefined.

[1, 4, -5, 10].find((n) => n < 0)
// -5

The above code finds the first one in the array that is less than 0 Members of .

[1, 5, 10, 15].find(function(value, index, arr) {
  return value > 9;
}) // 10

In the above code ,find The callback function of method can take three parameters , In order is the current value 、 Current position and original array .

Of the array instance findIndex Method usage and find The method is very similar , Returns the location of the first qualified array member , If all the members are not eligible , Then return to -1.

[1, 5, 10, 15].findIndex(function(value, index, arr) {
  return value > 9;
}) // 2

5.5、 Object extension

ES6 Allow in braces , Write variables and functions directly , Properties and methods as objects . This kind of writing is more concise .

const foo = 'bar';

const baz = {foo};

baz // {foo: "bar"}

//  Equate to const baz = {foo: foo};

Except for attribute shorthand , Methods can also be abbreviated .

const o = {

 	method() {

 	 	return "Hello!";

 	}
};

//  Equate to 

const o = {

 	method: function() {

  		return "Hello!";

 	}
};

New methods of object

Object.assign(target, source_1, ···)

Used to copy all enumerable properties of the source object to the target object .

Basic usage

let target = {a: 1}; 

let object2 = {b: 2}; 

let object3 = {c: 3}; 

Object.assign(target,object2,object3); //  The first parameter is the target object , The next parameter is the source object  
target; // {a: 1, b: 2, c: 3}

6、Class Basic use and inheritance

6.1、 Origin of classes

JavaScript In language , The traditional way to generate instance objects is through constructors . Here is an example .

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);

The above method is similar to the traditional object-oriented language ( such as C++ and Java) Difference is very big , It's easy to confuse new programmers learning the language .

ES6 Provides a more traditional approach , Introduced Class( class ) The concept , Template as object . adopt class keyword , Classes can be defined .

Basically ,ES6 Of class Can be seen as just a grammar sugar , Most of its functions ,ES5 Can do it , new class The writing method is just to make the writing method of the object prototype clearer 、 It's more like the syntax of object-oriented programming . The code above uses ES6 Of class rewrite , That's what it looks like .

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

The code above defines one “ class ”, You can see that there is a constructor Method , This is the construction method , and this Keyword represents instance object . in other words ,ES5 Constructor for Point, Corresponding ES6 Of Point Construction method of class .

Point Class in addition to construction methods , I've also defined one toString Method . Be careful , Definition “ class ” When , No need to add function This keyword , Just put in the function definition . in addition , Methods do not need to be separated by commas , If you add it, you will report an error .

6.2、constructor Method

constructor Method is the default method of a class , adopt new When the command generates an object instance , Call this method automatically . A class must have constructor Method , If not explicitly defined , An empty one constructor Method will be added by default .

class Point {
}

//  Equate to 
class Point {
  constructor() {}
}

In the above code , Defines an empty class Point,JavaScript The engine will automatically add an empty constructor Method .

6.3、 Class

Write the instance of the generated class , And ES5 Exactly the same as , Is also used new command . As I said before , If you forget to add new, Call... Like a function Class, Will be an error .

class Point {
  // ...
}

//  Report errors 
var point = Point(2, 3);

//  correct 
var point = new Point(2, 3);

6.4、 Class inheritance

Class Can pass extends Keyword implementation inheritance , This is more than ES5 By modifying the prototype chain to achieve inheritance , Be much clearer and more convenient .

class Point {
}

class ColorPoint extends Point {
}

super keyword

super This keyword , It can be used as a function , It can also be used as an object . In both cases , It's used in a completely different way .

Case one ,super When called as a function , Represents the constructor of the parent class .ES6 requirement , The constructor for the subclass must be executed once super function .

class A {}

class B extends A {
  constructor() {
    super();
  }
}

In the above code , Subclass B In the constructor of super(), Represents the constructor that calls the parent class . It's a must , otherwise JavaScript The engine will report an error .

The second case ,super As an object , In the ordinary way , Points to the prototype object of the parent class ; In a static method , Point to the parent class .

class A {
  p() {
    return 2;
  }
}

class B extends A {
  constructor() {
    super();
    console.log(super.p()); // 2
  }
}

let b = new B();

In the above code , Subclass B In the middle of super.p(), Will be super Used as an object . At this time ,super In the ordinary way , Point to A.prototype, therefore super.p() Equivalent to A.prototype.p().

6.5、 Static methods

The class is the stereotype of the instance , All methods defined in the class , Will be inherited by the instance . If it's before a method , add static keyword , Means that the method will not be inherited by the instance , It's called directly from the class , This is called a “ Static methods ”.

class Foo {
  static classMethod() {
    return 'hello';
  }
}

Foo.classMethod() // 'hello'

var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function

In the above code ,Foo Class classMethod There is before the method static keyword , It shows that this method is a static method , Can be directly in Foo Class call (Foo.classMethod()), Not in Foo Called on an instance of a class . If you call a static method on an instance , It throws an error , Means the method does not exist .

6.6、 Static attribute

The static property refers to Class Its own attributes , namely Class.propName, It's not defined in the instance object (this) Properties on .

class Foo {
}

Foo.prop = 1;
Foo.prop // 1

The above is written as Foo Class defines a static property prop.

at present , Only this way of writing works , because ES6 Make it clear ,Class There are only static methods inside , No static properties . Now there is a The proposal Provides static properties of the class , It is written in front of the instance property , add static keyword .

class MyClass {
  static myStaticProp = 42;

  constructor() {
    console.log(MyClass.myStaticProp); // 42
  }
}

This new method greatly facilitates the expression of static attributes .

//  Old style 
class Foo {
  // ...
}
Foo.prop = 1;

//  neographism 
class Foo {
  static prop = 1;
}

In the above code , The static properties of the old way are defined outside the class . After the whole class is generated , Then generate static attributes . This makes it easy to ignore this static property , It also does not comply with the code organization principle that relevant code should be put together . in addition , The new way to write it is to explicitly declare (declarative), Instead of assignment processing , Better semantics .

7、Set and Map data structure

7.1、Set

ES6 Provides a new data structure Set. It's like an array , But the values of the members are unique , There are no duplicate values .

Basic usage :

let mySet = new Set();
 
mySet.add(1); // Set(1) {1}
mySet.add(5); // Set(2) {1, 5}
mySet.add(5); // Set(2) {1, 5}  This shows the uniqueness of value 
mySet.add("some text"); 
// Set(3) {1, 5, "some text"}  There is a diversity of types 
var o = {a: 1, b: 2}; 
mySet.add(o);
mySet.add({a: 1, b: 2}); 
// Set(5) {1, 5, "some text", {…}, {…}} 
//  This shows the reference difference between objects , Even if the value is the same ,Set  Can also store 

The above code passes add() Method direction Set Structure join members , It turns out that Set Structure does not add duplicate values .

Set The function accepts an array ( Or with iterable Other data structures of the interface ) As a parameter , Used to initialize .

//  Patients with a 
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]

//  Example 2 
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5

Data type conversion

Array And Set Type conversion

// Array  turn  Set
var mySet = new Set(["value1", "value2", "value3"]);
//  use ... The operator , take  Set  turn  Array
var myArray = [...mySet];

//Array.from Method can  Set  Structure to array .
const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);

String And Set Type conversion

// String  turn  Set
var mySet = new Set('hello');  // Set(4) {"h", "e", "l", "o"}
//  notes :Set  in  toString  The way is not to  Set  convert to  String

Set Properties of instances

  • Set.prototype.constructor: Constructors , The default is Set function .
  • Set.prototype.size: return Set The total number of members of the instance .

Set Operation method of the instance

  • Set.prototype.add(value): Add a value , return Set Structure itself .
  • Set.prototype.delete(value): Delete a value , Returns a Boolean value , Indicates whether the deletion is successful .
  • Set.prototype.has(value): Returns a Boolean value , Indicates whether the value is Set Members of .
  • Set.prototype.clear(): Clear all members , no return value .

Code example :

s.add(1).add(2).add(2);
//  Be careful 2 Was added twice 

s.size // 2

s.has(1) // true
s.has(2) // true
s.has(3) // false

s.delete(2);
s.has(2) // false

Set Instance traversal method

  • Set.prototype.keys(): Returns the traverser of the key name
  • Set.prototype.values(): The traverser that returns the key value
  • Set.prototype.entries(): Returns the traverser of the key value pair
  • Set.prototype.forEach(): Use the callback function to traverse each member

It is important to note that ,Set The traversal order of is the insertion order . This feature is sometimes very useful , For example, use Set Save a list of callback functions , When called, it can be called in the order of addition .

Code example :

keys Method 、values Method 、entries Methods return traverser objects ( See 《Iterator object 》 chapter ). because Set Structure has no key name , Only key value ( Or the key name and the key value are the same value ), therefore keys Methods and values Methods behave exactly the same .

let set = new Set(['red', 'green', 'blue']);

for (let item of set.keys()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.values()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.entries()) {
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

forEach() Code example :

let set = new Set([1, 4, 9]);
set.forEach((value, key) => console.log(key + ' : ' + value))
// 1 : 1
// 4 : 4
// 9 : 9

The application of traversal

(1) Array weight removal

var mySet = new Set([1, 2, 3, 4, 4]);
[...mySet]; // [1, 2, 3, 4]

(2) Combine

var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var union = new Set([...a, ...b]); // {1, 2, 3, 4}

(3) intersection

var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var intersect = new Set([...a].filter(x => b.has(x))); // {2, 3}

(4) Difference set

var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var difference = new Set([...a].filter(x => !b.has(x))); // {1}

7.2、Map

Map Object to save key value pairs . Any value ( Object or original value ) Can be used as a key or as a value .

Basic usage :

const m = new Map();
const o = {p: 'Hello World'};

m.set(o, 'content')
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false

Map Medium key

key Is string

var myMap = new Map();
var keyString = "a string"; 
 
myMap.set(keyString, " Sum key 'a string' The value of the Association ");
 
myMap.get(keyString);    // " Sum key 'a string' The value of the Association "
myMap.get("a string");   // " Sum key 'a string' The value of the Association "
                         //  because  keyString === 'a string'

key It's the object

var myMap = new Map();
var keyObj = {}, 
 
myMap.set(keyObj, " Sum key  keyObj  The value of the Association ");

myMap.get(keyObj); // " Sum key  keyObj  The value of the Association "
myMap.get({}); // undefined,  because  keyObj !== {}

key Is the function

var myMap = new Map();
var keyFunc = function () {}, //  function 
 
myMap.set(keyFunc, " Sum key  keyFunc  The value of the Association ");
 
myMap.get(keyFunc); // " Sum key  keyFunc  The value of the Association "
myMap.get(function() {}) // undefined,  because  keyFunc !== function () {}

Map The traversal

Yes Map Traversal , The following two superlatives .

(1)for…of

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
 
//  Two will be displayed  log.  One is  "0 = zero"  The other is  "1 = one"
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
/*  This  entries  Method returns a new one  Iterator  object , It contains... In insertion order  Map  Of each element in the object  [key, value]  Array . */
 
//  Two will be displayed log.  One is  "0"  The other is  "1"
for (var key of myMap.keys()) {
  console.log(key);
}
/*  This  keys  Method returns a new one  Iterator  object ,  It contains... In insertion order  Map  The key of each element in the object . */
 
//  Two will be displayed log.  One is  "zero"  The other is  "one"
for (var value of myMap.values()) {
  console.log(value);
}
/*  This  values  Method returns a new one  Iterator  object , It contains... In insertion order  Map  The value of each element in the object . */

(2)forEach()

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
 
//  Two will be displayed  logs.  One is  "0 = zero"  The other is  "1 = one"
myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)

8、Promise The object of

8.1、Promise summary

Is a solution to asynchronous programming .

grammatically ,Promise It's an object , From it you can get messages for asynchronous operations .

Basic usage :

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/*  Asynchronous operation succeeded  */){
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

Promise The constructor takes a function as an argument , The two parameters of this function are resolve and reject. They are two functions , from JavaScript The engine provides , Don't deploy yourself .

resolve The delta function is going to be , take Promise Object state from “ Hang in the air ” Turn into “ success ”( From pending Turn into resolved), Called when the asynchronous operation succeeds , And the result of the asynchronous operation , Passed as a parameter ;reject The delta function is going to be , take Promise Object state from “ Hang in the air ” Turn into “ Failure ”( From pending Turn into rejected), Called when an asynchronous operation fails , Error reported by asynchronous operation , Passed as a parameter .

Promise After instance generation , It can be used then Methods specify resolved State and rejected Callback function for state .

then Method can take two callback functions as parameters . The first callback function is Promise The state of the object changes to resolved Called when the , The second callback function is Promise The state of the object changes to rejected Called when the . among , The second function is optional , It is not necessary to provide . Both of these functions accept Promise Object as a parameter .

8.2、Promise Characteristics of state

Promise There are three states of asynchronous operation :pending( Have in hand )、fulfilled( Have succeeded ) and rejected( Failed ). Except for the results of asynchronous operations , No other operation can change this state .

Promise The only object is : from pending Turn into fulfilled And from the pending Turn into rejected The state of change . As long as in fulfilled and rejected , The state will not change again, that is resolved( Have to finalize the design ).

const p1 = new Promise(function(resolve,reject){
    resolve('success1');
    resolve('success2');
}); 
const p2 = new Promise(function(resolve,reject){  
    resolve('success3'); 
    reject('reject');
});
p1.then(function(value){  
    console.log(value); // success1
});
p2.then(function(value){ 
    console.log(value); // success3
});

Disadvantages of state

Can't cancel Promise , Once it's created, it's executed immediately , Unable to cancel .

If you do not set the callback function ,Promise An error thrown internally , It doesn't react to the outside .

When in pending In the state of , It is impossible to know at what stage ( Just started or almost finished ).

8.3、Promise Methods

then() Method

then Method takes two functions as arguments , The first parameter is Promise Callback on success , The second parameter is Promise Callback on failure , Only one of the two functions will be called .

stay JavaScript Before the current run of the event queue is completed , Callback functions will never be called .

const p = new Promise(function(resolve,reject){
  resolve('success');
});
 
p.then(function(value){
  console.log(value);
});
 
console.log('first');
// first
// success

catch() Method

Promise.prototype.catch The method is .then(null, rejection) or .then(undefined, rejection) Another name for , Used to specify the callback function when an error occurs .

getJSON('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  //  Handle  getJSON  and   An error occurred while the previous callback function was running 
  console.log(' An error occurred !', error);
});

In the above code ,getJSON Method returns a Promise object , If the object state changes to resolved, It will call then Callback function specified by method ; If an asynchronous operation throws an error , The state is going to be zero rejected, Will call catch Callback function specified by method , Handle this error . in addition ,then Callback function specified by method , If an error is thrown while running , Will also be catch Methods to capture .

p.then((val) => console.log('fulfilled:', val))
  .catch((err) => console.log('rejected', err));

//  Equate to 
p.then((val) => console.log('fulfilled:', val))
  .then(null, (err) => console.log("rejected:", err));

all() Method

Promise.all() Method is used to add more than one Promise example , Pack into a new one Promise example .

const p = Promise.all([p1, p2, p3]);

In the above code ,Promise.all() Method takes an array as an argument ,p1p2p3 All are Promise example , If not , I'll call the following Promise.resolve Method , Convert parameter to Promise example , Further processing . in addition ,Promise.all() Method can be an array , But must have Iterator Interface , And every member returned is Promise example .

p The status of the p1p2p3 decision , There are two cases .

(1) Only p1p2p3 The state of fulfilled,p The state of fulfilled, here p1p2p3 The return value of consists of an array , Pass to p Callback function for .

(2) as long as p1p2p3 One of them was rejected,p The state of rejected, At this time, the first was reject The return value of the instance of , Will pass to p Callback function for .

Here is a concrete example .

//  Generate a Promise An array of objects 
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
  return getJSON('/post/' + id + ".json");
});

Promise.all(promises).then(function (posts) {
  // ...
}).catch(function(reason){
  // ...
});

In the above code ,promises Is included 6 individual Promise An array of instances , Only here 6 The state of each instance becomes fulfilled, Or one of them becomes rejected, Will call Promise.all Method .

9、async function

9.1、 Concept

ES2017 The standard introduces async function , Make asynchronous operation more convenient .

async What is a function ? In a word , It is Generator Grammatical sugar of function

9.2、 Basic usage

async The function returns a Promise object , have access to then Method to add a callback function . When the function executes , Once encountered await I'll come back first , Wait until the asynchronous operation is complete , Then execute the following statements in the function body .

Here is an example .

async function getStockPriceByName(name) {
  const symbol = await getStockSymbol(name);
  const stockPrice = await getStockPrice(symbol);
  return stockPrice;
}

getStockPriceByName('goog').then(function (result) {
  console.log(result);
});

The above code is a function to get the stock quotation , Before the function async keyword , Indicates that there are asynchronous operations inside the function . When the function is called , Will immediately return to a Promise object .

9.3、 grammar

async The function returns a Promise object .

async Internal function return The value returned by the statement , It's going to be then Method callback function parameters .

async function f() {
  return 'hello world';
}

f().then(v => console.log(v))
// "hello world"

In the above code , function f Inside return The value returned by the command , Will be then Method callback received .

async Error thrown inside function , Will result in a return Promise The object becomes reject state . The error object thrown will be catch Method callback received .

async function f() {
  throw new Error(' Something went wrong ');
}

f().then(
  v => console.log(v),
  e => console.log(e)
)
// Error:  Something went wrong 
原网站

版权声明
本文为[Front end Jiang Taigong]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/186/202207050842306103.html