1. Scope variables

Scope is the scope of a variable. That is, when you declare a variable, it can be used. JavaScript used to only have global scope, and function scope.

1.1 Problems with VAR

1. Var has no block-level scope and can be accessed in the current package after it is defined. If the variable name is repeated, it will overwrite the previously defined variable and can be modified by others.

if(true){
	var a = "a"; } console.log(a);Copy the code

2. Var marks variable sharing in the for loop. The I used in the loop is shared, essentially because there is no block-level scope

for (var i = 0; i < 3; i++) {
     setTimeout(function() { alert(i); }, 0); } // the result is popover 3 times 3for ( i = 0; i < 3; i++) {
     setTimeout(function() { alert(i); }, 0); } // the result is 0-2 pop-ups three timesCopy the code

1.2 block-level scope

When we used var to define variables, variables were isolated by closures. Now with let, we can not only isolate variables by closures, but also add some block-level scope isolation. Block-level functions use curly braces to define a fast, let-defined variable word that is inaccessible outside of curly braces.

1.2.1 Realization of accounting scope

if(ture){
	let name = 'wjh'
}

consloe.log('name'); // ReferenceError: name is not defined
Copy the code

1.2.2 Does not pollute global objects

if(ture){
	let name = 'wjh'
}
console.log(window.name); // undefined
Copy the code

1.2.3 I can also be used in the for loop

// Nested loops do not affect each otherfor (let i = 0; i < 3; i++) {
   console.log("out", i);
   for (let i = 0; i < 2; i++) {
   console.log("in", i); }} // Result out 0in 0 in 1 out 1 in 0 in 1 out 2 in 0 in 1
Copy the code

1.2.4 Repeated definitions may cause errors

if(ture){
	let a = 1;
  let a = 2; //Identifier 'a'
}
Copy the code

1.2.5 There is no pre-explanation of variables

for(leti = 0; i<2; i++){ console.log('inner',i);
  leti =100; } // I is not definedCopy the code

1.2.6 A new way to write closures

; (function() () {});Copy the code

now

{}Copy the code

2. The constant

Using const we can declare a constant. Once declared, it cannot be changed.

2.1 Constants cannot be reassigned

const MY_NAME = 'wjw';
MY_NAME = 'wjw2';//Assignment to constant variable
Copy the code

2.2 Variables can be changed

Note that const limits the ability to reassign a value to a variable. The value of a variable itself can be changed

const names = ['wjw1'];
names.push('wjw2');
console.log(names);
Copy the code

2.3 Different block-level scopes can be defined multiple times

const A = "0";
{
    const A = "A";
    console.log(A)
}
{
    const A = "B";
    console.log(A)
}
console.log(A)

// result A B 0
Copy the code

3. The deconstruction

3.1 Deconstructing an Array

Deconstruction means to break down the structure of something, you can define N variables in a way that’s like an array, you can assign values from an array according to rules.

var [name,age]=['wjh'.8];
console.log(name,age);
Copy the code

3.2 Nested assignment

let [x,[y],z]=[1[2.1]].console.log(x,y,z);

let [x,[y,z]] = [1[2.1.2.2]].console.log(x,y,z);

let [json,arr,num] = [{name:'wjw'},1.2].3];
console.log(json,arr,num);

// 1 2.1 undefined 1 2.1 2.2 {name: 'WJW'} [1, 2] 3
Copy the code

3.3 Omit assignment

let [,,x]=[1.2.3]
console.log(x);
Copy the code

3.4 Deconstructing Objects

Objects can also be deconstructed

var obj = {name:'wjw'.age:8};
The value of the name attribute in the object is passed to the name variable, and the value of the age attribute is passed to the age variable
var {name,age} = obj
// The value of the name property in the object is passed to myname and the value of age is passed to myage
let {name: myname, age: myage} = obj;
console.log(name,age,myname,myage);
Copy the code

The default value of 3.5

Default values can be used for assignment and parameter passing

let [a='a',b='b',c=new Error('C must be specified ')] = [1.3];
console.log(a,b,c);

function ajax(options){
	var method = options.method || "get";
  var data = options.data || {};
}

function ajax(method='get',data){
	console.log(arguments);
}

ajax({
	method:'post'.data: {'name':'wjh'}})Copy the code

4. The string

4.1 Template Strings

The template string is contained with the reaction number (the one to the left of the number 1), enclosed in ${}

var name = 'wjw',age = 8;
let desc = `${name} is ${age}old! `;
console.log(desc);

// All whitespace and newlines in template strings are reserved
var str = `<ul>
<li>a</li>
<li>b</li>
</ul>`;
console.log(str);
Copy the code

The variables are replaced by their values

function replace(desc){
	return desc.replace(/\$\{([^}]+)\}/g.function(matched,key){
    return eval(key);
  });
}
Copy the code

4.2 Tagged Template Strings

You can add a label to the template string, So this tag can handle template strings and the tag is actually a function, and the function can take two arguments, one is strings which is the character of each part of the template string and one argument, which is rest value, which is the value of the template string.

var name = 'wjh',age = 8;
function desc(strings,... values){
    console.log(strings,values);
}
desc`${name} is ${age}old! `;
Copy the code

New string methods

  • Includes () : Returns a Boolean value indicating whether the parameter string was found.
  • StartsWith () : Returns a Boolean value indicating whether the parameter string is at the head of the source string.
  • EndsWith () : Returns a Boolean value indicating whether the parameter string is at the end of the source string.
var s = 'wjh';
s.startsWith('w') // true
s.endsWith('h') // true
s.includes('j') // true
Copy the code

The second parameter indicates where the search begins

var s = 'wjh';
console.log(s.startsWith('j', 2)); //true
console.log(s.endsWith('j', 2)); //true
console.log(s.includes('j', 2)); //false
Copy the code

EndsWith behaves differently from other methods. It works for the first n characters, whereas other methods start at the number of characters and end of the string

4.4 repeat

The repeat method returns a new string, repeating the original string n times.

 'x'.repeat(3);
 'x'.repeat(0);
Copy the code

5. The function

5.1 Default Parameters

You can set default values for parameters received by a defined function. If the function is executed without specifying a value for the parameters of the function, these default values are used.

function ajax(url,method='GET',dataType="json"){
  console.log(url);
  console.log(method);
  console.log(dataType);
}
Copy the code

5.2 Expanding operators

Put the… You can expand an array by putting it in front of an array. You can expand a function without using apply

// Pass in parameters
let print = function(a,b,c){
    console.log(a,b,c);
}
print([1.2.3]); print(... [1.2.3]);

// Can replace apply
var m1 = Math.max.apply(null[8.9.4.1]);
var m2 = Math.max(... [8.9.4.1]);

// Can replace concat
var arr1 = [1.3];
var arr2 = [3.5];
var arr3 = arr1.concat(arr2);
var arr4 = [...arr1, ...arr2];
console.log(arr3,arr4);

// Class array to array
function max(a,b,c) {
    console.log(Math.max(... arguments)); } max(1.3.4);
Copy the code

5.3 Remaining Operators

The residual operator puts the values of the remaining arguments in an array called b

let rest = function(a,... rest){
    console.log(a,rest);
}
rest(1.2.3);
Copy the code

5.4 Deconstructing Parameters

let destruct = function({name,age}){
	console.log(name,age);
}
destruct({name:'wjh'.age:10})
Copy the code

5.6 Arrow Function

Arrow functions simplify the way functions are defined

[1.2.3].forEach(val= >console.log(val));
Copy the code

If there is more than one input parameter to be included with (), the function body should be wrapped with {} if there are more than one statements

The arrow function does not have its own this at all, resulting in the inner this being the this of the outer code block. Precisely because it does not have this, the problem of this pointing to is avoided.

var person = {
    name:'wjh'.getName:function(){
-        setTimeout(function(){console.log(this); },1000); // This points to window when executed in the browser
+        setTimeout((a)= > console.log(this),1000);// This points to person when executed in the browser
    }
}
person.getName();
Copy the code

6. New methods for arrays

// Same array
var people = [
  {
    name : 'Casper' ,
    like : 'Spaghetti in a pan' ,
    age : 18
  },
  {
    name : 'Wang' ,
    like : 'Fried noodles' ,
    age : 24
  },
  {
    name : 'Bobo' ,
    like : 'Puree of radish' ,
    age : 1
  },
  {
    name : 'marinated egg' ,
    like : 'Puree of radish' ,
    age : 3}];Copy the code

6.1 Array. The prototype. The filter ()

Filter () returns an array of objects whose conditions are true after return, which is ideal for searching for qualified data.

var filterEmpty = people.filter( function( item, index, array ) { }); console.log(filterEmpty); Var filterAgeThan5 = people.filter(function ( item, index, array ) {
  returnitem.age > 5 ; });}); console .log(filterAgeThan5); // Casper, WangCopy the code

6.2 Array. The prototype. The find ()

Find () is similar to filter(), except that find() returns a value that is true the first time.

var findEmpty = people.find( function ( item, index, array ) {});console .log(findEmpty);           // undefined if there is no condition

var findAgeThan5 = people.find( function ( item, index, array ) {
  return item.age > 5 ;            // Get over 5 years old
});

console .log(findAgeThan5);        // There are two answers, but only one Casper is returned
var findLike = people.find( function ( item, index, array ) {
  return item.like === 'Puree of radish' ;   // Get array like === 'turnip'
});
console .log(findLike);            // Although there are two answers, only the first Bobo object will be returned
Copy the code

6.3 Array. The prototype. The forEach ()

ForEach is the simplest of these array functions. It does not return additional values, but simply executes objects or values within each array.

var forEachIt = people.forEach( function ( item, index, array ) {
  console .log(item, index, array); // Object, index, all array
  return item;                      // forEach is not in return, so it doesn't matter
});

console .log(forEachIt);             // undefined

people.forEach( function ( item, index, array ) {
  item.age = item.age + 1 ;          // forEach is like for, but easier to write
});
console .log(people);                // All age + 1
Copy the code

6.4 Array. The prototype. The map ()

When using map() he needs to return a value, he will combine the values returned from the function into an array. If not, undefined the number of returns is equal to the length of the original array which is good for taking the original variables and recomposing them into a new array.

var mapEmpty = people.map( function ( item, index, array ) {});console .log(mapEmpty);     // [undefined, undefined, undefined, undefined]

var mapAgeThan5 = people.map( function ( item, index, array ) {
  return item.age > 5 ;     // Compare those older than five
});
console .log(mapAgeThan5); // [true, true, false, false]

var mapAgeThan5_2 = people.map( function ( item, index, array ) {
  // Error
  if (item.age > 5 ) {
    return item;               // Return a message older than 5 years old
  }
  return  false ;                // Do not assume that empty or false will not return
});
console .log(mapAgeThan5_2);    // [{name: 'Casper'...}, {name: 'Wang'...}, false, false]
var mapEat = people.map( function ( item, index, array ) {
  if(item.like ! = ='Puree of radish' ) {
    return  ` ${item.like}Yummy ' ;
  } else {
    return  ` ${item.like}It doesn't taste good `; }});console .log(mapEat);           // [" pot roast pasta delicious ", "fried noodles delicious "," radish mud not delicious ", "radish mud not delicious "]
Copy the code

6.5 Array. Prototype. Every ()

Every () checks that all arrays meet the criteria. This returns only one value, trueor False, which can be used to check that the contents of an array meet the criteria.

var ans = array.every( function ( item, index, array ) {
  console .log(item, index, array); // Object, index, all array
  return item.age > 10  // Return true only when all ages are greater than 10
});
console .log(ans); // false: If some parts do not match, the value is false

var ans2 = array.every( function ( item, index, array ) {
  return item.age < 25
});
console .log(ans2); // true: All ages are less than 25
Copy the code

6.6 Array. Prototype. Some ()

Some () is very similar to every(), which returns true or false, except that every() needs to be completely true and some() only needs to be partially true.

var ans = people.some( function ( item, index, array ) {
  return item.age > 10  // Return true only when all ages are greater than 10
});
console .log(ans);   // true: true as long as some matches are true

var ans2 = people.some( function ( item, index, array ) {
  return item.age < 25
});
console .log(ans2); // true: true as long as some matches are true

var ans2 = people.some( function ( item, index, array ) {
  return item.age > 25
});
console .log(ans2); // false: false if all of them do not match
Copy the code

6.7 Array. The prototype. The reduce ()

Accumulator: The accumulator parameter, if the first array is an accumulator, is the additional value currentValue that was passed in or initialized with: CurrentIndex: indicates the currentIndex. Array: indicates all arrays

var reduceEmpty = people.reduce( function ( accumulator, currentValue, currentIndex, array ) {});console .log(reduceEmpty);                  // undefined if there is no condition

var reducePlus = people.reduce( function ( accumulator, currentValue, currentIndex, array ) {
  // Are the previous return value, the current value, and the current index value respectively
  console .log(accumulator, currentValue, currentIndex);
  return accumulator + currentValue.age;   // Add to the previous value
}, 0 );                                     // Pass in an initialization value of 0
console .log(reducePlus);                   // The total is 46

var reducePlus = people.reduce( function ( accumulator, currentValue, currentIndex, array ) {
  console .log( 'reduce' , accumulator, currentValue, currentIndex)
  return  Math .max( accumulator, currentValue.age ); // Which value is larger than the previous value
}, 0 );
console .log(reducePlus);                   // Maximum value is 24
Copy the code

Object of 7.

7.1 Object literals

If you want to add properties to an object that are the same as the name of the variable, and the value of the property is the value of the variable, you can add those properties directly to the object

let name = 'wjh';
let age = 8;
let getName = function(){
		console.log(this.name)
}
let person ={
		name,
    age,
    getName
}
person.getName();
Copy the code

7.2 the Object is

Compare two values to see if they are equal

console.log(Object.is(NaN.NaN));
Copy the code

7.3 the Object. The assign

To copy properties of multiple objects into one object, the first parameter is the copied object, and from the second parameter onwards, the copied source object

var nameObj = {name:'wjh'}
var ageObj = {age:8};
var obj = {};
Object.assign(obj,nameObj,ageObj);
console.log(obj);

// Clone objects
function clone(obj){
	return Object.assgin({},obj);
}
Copy the code

7.4 Object. SetPrototypeOf

Sets a specified object stereotype to another object or null

var obj1 = {name:'wjh1'};
var obj2 = {name:'wjh2'};
var obj = {};
Object.setPrototypeOf(obj,obj1);
console.log(obj.name);
console.log(Object.getPrototypeOf(obj));
Object.setProtoypeOF(obj,obj2);
console.log(obj.name);
console.log(Object.getPrototypeOf(obj));
Copy the code

7.5 proto

Set Prototype in the direct object expression

var obj1 = {name:'wjh'};
var obj3 = {
	_proto_:obj1
} 
console.log(obj3.name);
console.log(Object.getPrototypeOf(obj3));
Copy the code

7.6 super

You can call properties or methods on proType through super

let person ={
	eat(){
  	return 'milk'; }}let student = {
	_proto_:person,
  eat(){
  	return super.eat()+'bead'}}console.log(student.eat());
Copy the code

Class 8.

8.1 the class

Defining a class using the class keyword creates an instance based on which the constructor method is created, which can be used to initialize

class Person{
	constructor(name){
  	this.name = name;
  }
  
  getName(){
		console.log(this.name)  
  }

}

let person = new Person('wjh');
person.getName();
Copy the code

8.2 the get and set

Getters are for getting properties, setters are for setting properties

class Person {
	constructor() {this.hobbies = [];
  }
  set hobby(hobby){
  	this.hobbies.push(hobby);
  }
  get hobby(){
  	return this.hobbies; }}let person = new Person();
person.hobby = 'aa';
person.hobby = 'bb';
console.log(person.hobby)
Copy the code

8.3 Static Method: Static

You can use the keyword static to add static methods to a class. Static methods are methods that can be used without instantiating the class

class Person{
	static add(a,b){
  	returna+b; }}console.log(Person.add(1,x));
Copy the code

8.4 inheritance extends

A class can inherit from other classes

class Person{
	constructor(name){
  	this.name = name; }}class Teacher extends Person{
	constructor(name,age){
  	super(name);
    this.age = age; }}var teacher = Teacher('wjh'.8);
console.log(teacher.name,teacher.age)
Copy the code

9. Generators and Iterators

Generator is a special function that returns an Iterator object. By iterating over an iterator, Generator function execution regrets returning the iterator object instead of the function’s return value.

9.1 Iterators simulation

The iterator has a next method that returns an object every time it executes and the object has two functions in it, one is value for the returned value, and the other is Boolean done for the completion of the iteration

function buy(books){
  let i = 0;
  return{
    next(){
      let done = i ===books.length;
      letvalue = ! done ? books[i++]:undefined;
      return {
      	value:value,
        done:done
      }
    }
  }
}

let iterators = buy(['js'.'html']);
var curr;
do{
	curr = iterators.next();
  console.log(curr);
}while(! curr.done);Copy the code

9.3 Generators

Generators are used to create iterators

function* buy(boos){ for(var i=0; i<boos.length; i++){ yield books[i]; } } let buying = buy(['js','html]); var curr; do { curr = buying.next(); console.log(curr); }while(! curr.done);Copy the code

Collection of 10.

10.1 the Set

A Set is a collection of things. A Set is kind of like an array, except that unlike an array, there can’t be duplicate contents in a Set

var books = new Set(a); books.add('js');
books.add('js');// The number of elements in the set to which repeating elements are added does not change
books.add('html');
books.forEach(function(book){ // loop set
	console.log(book);
})
console.log(book.size);// The number of elements in the set
console.log(books.has('js'));// Determine if the collection has this element
books.delete('js');
console.log(books.size);
console.log(books.has('js'));
books.clear();/ / empty set
console.log(books.size);
Copy the code

10.2 the Map

You can use a Map to organize the data for this name-value pair

var books = new Map(a); books.set('js', {name:'js'});// Add elements to the map
books.set('html', {name:'html'});
console.log(books.size);// View the elements in the collection
console.log(books.get('js'));// Get the value by key
books.delete('js');// Execute key to remove elements
console.log(books.has('js'));// Check whether there are keys in the map
book.forEach((value,key) = >{
	console.log(key+'='+value);
})
books.clear();/ / empty map
Copy the code

11. The module

You can divide your code into modules based on the needs of your application, and each module can export things that it needs to be used by other modules, and from other modules you can import those modules, export things.

11.1 module

Using a module in a browser requires an export

export var name = 'wjh';
export var age = 8;
Copy the code

The import

//import {name,age} from './school.js';
import * as school from './school.js';
console.log(school.name,school.age);
Copy the code

Reference in the page

<script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script>
<script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script>
<script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
<script type="module" src="index.js"></script>
Copy the code

11.2 rename

Rename when exporting

function say(){
	console.log('say');
}
export {say as say2};
Copy the code

Rename when importing

import {say2 as say3} from './school.js'
Copy the code

11.3 Default Export

Each module can have a default to export

export default function say(){
	console.log('say')}Copy the code

The import

import say from './school.js'
Copy the code

11.4 Deep Clone

var parent = {
  age: 5.hobby: [1.2.3].home: {city: 'Beijing'}};var child = extendDeep(parent);
child.age = 6;
child.hobby.push('4');
child.home.city = 'in guangdong';
console.log('child ', child); / / [1, 2, 3, 4]
console.log('parent ', parent);
function extend(parent) {
  let child;
  if (Object.prototype.toString.call(parent) == '[object Object]') {
    child = {};
    for (let key in parent) {
      child[key] = extend(parent[key])
    }
  } else if (Object.prototype.toString.call(parent) == '[object Array]') {
    child = parent.map(item= > extend(item));
  } else {
    return parent;
  }
  return child;
}

function extendDeep(parent, child) {
  child = child || {};
  for (var key in parent) {
    if (typeof parent[key] === "object") {
      child[key] = (Object.prototype.toString.call(parent[key]) === "[object Array]")? [] : {}; extendDeep(parent[key], child[key]); }else{ child[key] = parent[key]; }}return child;
}
Copy the code

12. Conditional statements in JavaScript(ES6

12.1 Use array.includes to handle multiple conditions

function test(fruit) {
  if (fruit == 'apple' || fruit == 'strawberry') {
    console.log('red'); }}Copy the code

Optimization becomes ->>

function test(fruit) {
  // The condition is extracted into the array
  const redFruits = ['apple'.'strawberry'.'cherry'.'cranberries'];
 
  if (redFruits.includes(fruit)) {
    console.log('red'); }}Copy the code

12.2 Reduce Nesting and Use return Statements in Advance

function test(fruit, quantity) {
  const redFruits = ['apple'.'strawberry'.'cherry'.'cranberries'];
 
  // Condition 1: fruit must have a value
  if (fruit) {
    // Condition 2: must be red
    if (redFruits.includes(fruit)) {
      console.log('red');
 
      // Condition 3: Quantity must be greater than 10
      if (quantity > 10) {
        console.log('big quantity'); }}}else {
    throw new Error('No fruit! '); }}// Test results
test(null); // Throw error: No fruits
test('apple'); // Print: red
test('apple'.20); // Print: red, big quantity
Copy the code

To optimize the

Return */ if invalid condition is found
 
function test(fruit, quantity) {
  const redFruits = ['apple'.'strawberry'.'cherry'.'cranberries'];
 
  // Condition 1: Throw an error ahead of time
  if(! fruit)throw new Error('No fruit! ');
 
  // Condition 2: must be red
  if (redFruits.includes(fruit)) {
    console.log('red');
 
    // Condition 3: Quantity must be greater than 10
    if (quantity > 10) {
      console.log('big quantity'); }}}Copy the code

To reduce one level of nesting, optimize the coding style

Return */ if invalid condition is found
 
function test(fruit, quantity) {
  const redFruits = ['apple'.'strawberry'.'cherry'.'cranberries'];
 
  if(! fruit)throw new Error('No fruit! '); // Condition 1: Throw an error ahead of time
  if(! redFruits.includes(fruit))return;  // Condition 2: Return early when fruit is not red
 
  console.log('red');
 
  // Condition 3: Must be abundant
  if (quantity > 10) {
    console.log('big quantity'); }}Copy the code

12.3. Use default arguments and destructions for functions

function test(fruit, quantity) {
  if(! fruit)return;
  const q = quantity || 1; // If no quantity argument is provided, the default is 1
 
  console.log(`We have ${q} ${fruit}! `);
}
 
// Test results
test('banana'); // We have 1 banana!
test('apple'.2); // We have 2 apple!
Copy the code

But q doesn’t show all the optimizations here

function test(fruit, quantity = 1) { // I defaults to 1 if no quantity argument is provided
  if(! fruit)return;
  console.log(`We have ${quantity} ${fruit}! `);
}
 
// Test results
test('banana'); // We have 1 banana!
test('apple'.2); // We have 2 apple!
Copy the code

But this side could also be an object

// Destruct -- just get the name attribute
// Parameter default allocation of empty object {}
function test({name} = {}) {
  console.log (name || 'unknown');
}
 
// Test results
test(undefined); // unknown
test({ }); // unknown
test({ name: 'apple'.color: 'red' }); // apple
Copy the code

12.4 Choosing Map/Object Literals over Switch statements

function test(color) {
  // Use the switch case statement to find the corresponding fruit by color
  switch (color) {
    case 'red':
      return ['apple'.'strawberry'];
    case 'yellow':
      return ['banana'.'pineapple'];
    case 'purple':
      return ['grape'.'plum'];
    default:
      return[]; }}// Test results
test(null); / / []
test('yellow'); // ['banana', 'pineapple']
Copy the code

Here I suggest using objects for clarity

// Use the object literal to find the corresponding fruit by color
  const fruitColor = {
    red: ['apple'.'strawberry'].yellow: ['banana'.'pineapple'].purple: ['grape'.'plum']};function test(color) {
  return fruitColor[color] || [];
}
Copy the code

However, this side is probably network data, and variables such as RED cannot be determined, so arry. Filter is used to filter

const fruits = [
    { name: 'apple'.color: 'red' }, 
    { name: 'strawberry'.color: 'red' }, 
    { name: 'banana'.color: 'yellow' }, 
    { name: 'pineapple'.color: 'yellow' }, 
    { name: 'grape'.color: 'purple' }, 
    { name: 'plum'.color: 'purple'}];function test(color) {
  // Use Array filter to find the corresponding fruit by color
 
  return fruits.filter(f= > f.color == color);
}
Copy the code

12.5 Use array. every and array. some to handle all/part of the condition

We want to check that all the fruit is red

const fruits = [
    { name: 'apple'.color: 'red' },
    { name: 'banana'.color: 'yellow' },
    { name: 'grape'.color: 'purple'}];function test() {
  let isAllRed = true;
 
  // Condition: All fruit must be red
  for (let f of fruits) {
    if(! isAllRed)break;
    isAllRed = (f.color == 'red');
  }
 
  console.log(isAllRed); // false
}
Copy the code

Use arry. Every to filter

const fruits = [
    { name: 'apple'.color: 'red' },
    { name: 'banana'.color: 'yellow' },
    { name: 'grape'.color: 'purple'}];function test() {
  // Condition: Short way, all fruit must be red
  const isAllRed = fruits.every(f= > f.color == 'red');
 
  console.log(isAllRed); // false
}
Copy the code

If we want to check if at least one fruit is red, we can use array.some with just one line of code

const fruits = [
    { name: 'apple'.color: 'red' },
    { name: 'banana'.color: 'yellow' },
    { name: 'grape'.color: 'purple'}];function test() {
  // Condition: is there any red fruit
  const isAnyRed = fruits.some(f= > f.color == 'red');
 
  console.log(isAnyRed); // true
}
Copy the code

13 promise

13.1 Asynchronous Callback

13.1.1 Callback hell

When multiple operations are required, multiple callback functions are nested, resulting in unintuitive code, often referred to as callback hell

13.1.2 Parallel results

If several asynchronous operations are not in sequence, but the subsequent tasks can be executed only after the asynchronous operations are completed, the parallel operation cannot save time

13.2 Promise

I’ll make a promise to you after a certain amount of time. When will it be used over a period of time? The answer is asynchronous operations, which are things that take a long time to produce results, such as network requests, reading local files, etc

13.3 Three states of Promise

  • Pending Promise Specifies the initialization state of an object when its power is created
  • This can be interpreted as a state of success
  • Rejected = Rejected

The then method is used to specify the actions that will be performed when the state of the Promise object changes. The first function (onFulfilled) will be performed in resolve, and the second function (onFulfilled) will be performed in reject.

13.4 Constructing a Promise

13.4.1 use Promise

let promise = new Promise((resolve,reject) = >{
		setTimeout((a)= >{
    	if(Math.random()>0.5)
      	resolve('This is resolve! ')
      else
      	reject('This is reject')},1000);
});
promise.then(Fulfilled,Rejected)
Copy the code
  • Constructing a Promise instance requires passing a function to the Promise constructor
  • The function passed in requires two parameters, both of which are parameters of type function.
    • The first parameter will leave the Promise instance in the resolve state, so we typically name the first parameter resolve to change the Promise object’s state to success and pass a parameter for subsequent successful operations
    • The first parameter runs regret leaving the Promise instance in reject state, so we typically name the first parameter reject, changing the state of the Promise object to fail and passing the error information to subsequent error-handling operations

13.4.2 ES5 Simulates Promises

function Promise(fn){
	this.success(data);
},(error)=>{
	this.error();
}

Promise.prtotype.resolve = function (data){
	this.success(data);
}

Promise.prototype.then = function (success,error){
	this.success = success;
	this.error = error;
}
Copy the code

13.4.3 ES5 Simulates Promises

class Promise{
	constructor(fn){
  		fn((data) = >{
      	this.success(data);
      },(error)=>{
      	this.error();
      })
  }
  
  resolve(data){
  	this.success(data);
  }
  
  reject(error){
  	this.error(error);
  }
  
  then(success,error){
  	this.success = success;
    this.error = error;
    console.log(this); }}Copy the code

13.5 Promise is returned by the function

function ajaxPromise(queryUrl){
	return new Promise((resolve,reject) = >{
  	xhr.open('GET',queryUrl,ture);
    xhr.send(null);
    xhr.onreadystatechange = (a)= >{
    		if(xhr.readyState === 4) {if(xhr.status === 200){
          	resolve(xhr.responseText);
          }else{
          	reject(xhr.responseText);
          }
        }
    }
  })
}


ajaxPromise('http://www.baidu.com')
	.then((value) = >{
  	console.log(value);
  })
  .catch((err) = >{
  	console.error(err);
 });
Copy the code

13.6 Chain invocation of promise

  • Each call returns a new Promise instance
  • Arguments to chained calls are passed by return values

Then can be written as a chained call because it always returns a Promise object each time the method is executed

readFile('1.txt').then(function(data){
	console.log(data);
}).then(function (data){
	console.log(data);
  return readFile(data);
}).then(function (data){
	console.log(data);
}).catch(function (err){
	console.log(err);
})
Copy the code

13.7 promise API

13.7.1 Promise. All

  • Arguments: Accepts an array of Promise instances
  • Return value: Returns a Promise instance whose state transition depends on the state change of the parameter’s Promise instance. When the parameter is in the resolve state, the resolve state is returned. If either instance of the argument is reject, the returned Promise instance becomes REJECT.
Promise.all([p1,p2]).then(function(result){
	console.log(result); //[ '2.txt', '2' ]
})
Copy the code

No matter which of the two promises completes first, the promise. all method returns the results in the order in the array

13.7.2 Promise. Race

  • Arguments: Accepts an array of Promise instances
  • Return value: Returns a Promise instance whose state transition depends on the state change of the parameter’s Promise instance. When the parameter is in the resolve state, the resolve state is returned. If either instance of the argument is reject, the returned Promise instance becomes REJECT.
Promise.race([p1,p2]).then(function(result){
	console.log(result); //[ '2.txt', '2' ]
})
Copy the code

13.7.3 Promise. Resolve

Return an instance of Promise in the resolve state. Different functions depending on the parameters passed in:

  • Values (objects, arrays, strings, and so on): Values passed as resolve
  • Promise instance: return unchanged

Promise.reject

Return a Promise instance in reject state

  • Arguments are generally thrown error messages.

13.8 q

Q is a module that implements promises in javascript

13.8.1 Basic usage of Q

var Q = require('q');
var fs = require('fs');
function read(filename){
	var deferred = Q.defer();
  fs.readFile(filename,'utf8'.function) (err,data){
  	if(err){
    	deferred.reject(err);
    }else{ deferred.resolve(data); }}); } read('1.txt1').then(function(data){
	console.log(data);
},funtcion(error){
	console.error(error);                    
})
Copy the code

A simple implementation of 13.8.2 Q

module.exports = {
    defer(){
        var _success,_error;
        return {
            resolve(data){
                _success(data);
            },
            reject(err){
                _error(err);
            },
            promise:{
                then(success,error){
                    _success = success;
                    _error = error;
                }
            }
        }
    }
}
Copy the code

13.8.3Q implementation

var defer = function () {
    var pending = [], value;
    return {
        resolve: function (_value) {
            if (pending) {
                value = _value;
                for (var i = 0, ii = pending.length; i < ii; i++) {
                    var callback = pending[i];
                    callback(value);
                }
                pending = undefined; }},promise: {
            then: function (callback) {
                if (pending) {
                    pending.push(callback);
                } else{ callback(value); }}}}; };Copy the code

13.9 bluebird

The library that implements the Promise standard is the most full-featured and fastest

13.9.1 Bluebird classic use

var Promise = require('./bluebird');

var readFile = Promise.promisify(require("fs").readFile);
readFile("1.txt"."utf8").then(function(contents) {
    console.log(contents);
})

var fs = Promise.promisifyAll(require("fs"));

fs.readFileAsync("1.txt"."utf8").then(function (contents) {
    console.log(contents);
})
Copy the code

13.9.2 Bluebird simple implementation

module.exports = {
    promisify(fn){
        return function () {
            var args = Array.from(arguments);
            return new Promise(function (resolve, reject) {
                fn.apply(null, args.concat(function (err) {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(arguments[1])}})); }) } }, promisifyAll(obj){for(var attr in obj){
            if(obj.hasOwnProperty(attr) && typeof obj[attr] =='function'){
                obj[attr+'Async'] = this.promisify(obj[attr]); }}returnobj; }}Copy the code

13.10 the animation

<! DOCTYPE html><html lang="en">
<head>
    <meta charset="UTF-8">
    <title>move</title>
    <style>
        .square{
            width:40px;
            height:40px;
            border-radius: 50%;
        }
        .square1{
            background-color: red;
        }
        .square2{
            background-color: yellow;
        }
        .square3{
            background-color: blue;
        }
    </style>
</head>
<body>
<div class="square square1" style="margin-left: 0"></div>
<div class="square square2" style="margin-left: 0"></div>
<div class="square square3" style="margin-left: 0"></div>
</body>
<script>
  var square1 = document.querySelector('.square1');
  var square2 = document.querySelector('.square2');
  var square3 = document.querySelector('.square3');

  /*function move(element,target,resolve){ let timer = setInterval(function(){ var marginLeft = parseInt(element.style.marginLeft, 10); if(marginLeft == target){ resolve(); }else{ element.style.marginLeft = ++marginLeft+'px'; }}, 13); } * /
  function move(element,target,resolve){
    let current = 0;
    let timer = setInterval(function(){
      element.style.transform=`translateX(${++current}px)`;
      if(current>target){
        clearInterval(timer);
        resolve();
      };
    },13);
  }
  function animate(element,target){
    return new Promise(function(resolve,reject){
      move(element,target,resolve);
    });
  }
  animate(square1,100)
    .then(function(){
      return animate(square2,100);
    })
    .then(function(){
      return animate(square3,100);
    });
</script>
</html>
Copy the code

13.11. co

13.11.1 Co Initial Experience

let fs = require('fs');
function getNumber(){
  return new Promise(function (resolve,reject) {
    setTimeout(function(){
      let number = Math.random();
      if(number >. 5){
        resolve(number);
      }else{
        reject('Numbers too small'); }},1000);
  });
}
function *read(){
  let a = yield getNumber();
  console.log(a);
  let b = yield 'b';
  console.log(b);
  let c = yield getNumber();
  console.log(c);
}

function co(gen){
  return new Promise(function(resolve,reject){
    let g = gen();
    function next(lastValue){
      let {done,value} = g.next(lastValue);
      if(done){
         resolve(lastValue);
      }else{
        if(value instanceof Promise){
          value.then(next,function(val){
            reject(val);
          });
        }else{
          next(value);
        }
      }
    }
    next();
  });
}
co(read).then(function(data){
  console.log(data);
},function(reason){
  console.log(reason);
});
Copy the code

13.11.2 CO Continuously Reads Files

let fs = require('fs');
function readFile(filename){
  return new Promise(function (resolve,reject) {
    fs.readFile(filename,'utf8'.function(err,data){
      if(err)
        reject(err);
      elseresolve(data); })}); }function *read(){
  let a = yield readFile('./1.txt');
  console.log(a);
  let b = yield readFile('./2.txt');
  console.log(b);
}

function co(gen){
  let g = gen();
  function next(val){
    let {done,value} = g.next(val);
    if(! done){ value.then(next); } } next(); }Copy the code

13.12 Promise/A+ Full implementation

function Promise(executor) {
  let self = this;
  self.status = "pending";
  self.value = undefined;
  self.onResolvedCallbacks = [];
  self.onRejectedCallbacks = [];
  function resolve(value) {
    if (value instanceof Promise) {
      return value.then(resolve, reject)
    }
    setTimeout(function () { // Execute all callbacks asynchronously
      if (self.status == 'pending') {
        self.value = value;
        self.status = 'resolved';
        self.onResolvedCallbacks.forEach(item= >item(value)); }}); }function reject(value) {
    setTimeout(function () {
      if (self.status == 'pending') {
        self.value = value;
        self.status = 'rejected';
        self.onRejectedCallbacks.forEach(item= >item(value)); }}); }try {
    executor(resolve, reject);
  } catch(e) { reject(e); }}function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === x) {
    return reject(new TypeError('Circular reference'));
  }
  let then, called;

  if(x ! =null && ((typeof x == 'object' || typeof x == 'function'))) {
    try {
      then = x.then;
      if (typeof then == 'function') {
        then.call(x, function (y) {
          if (called)return;
          called = true;
          resolvePromise(promise2, y, resolve, reject);
        }, function (r) {
          if (called)return;
          called = true;
          reject(r);
        });
      } else{ resolve(x); }}catch (e) {
      if (called)return;
      called = true; reject(e); }}else{ resolve(x); }}Promise.prototype.then = function (onFulfilled, onRejected) {
  let self = this;
  onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : function (value) {
    return value
  };
  onRejected = typeof onRejected == 'function' ? onRejected : function (value) {
    throw value
  };
  let promise2;
  if (self.status == 'resolved') {
    promise2 = new Promise(function (resolve, reject) {
      setTimeout(function () {
        try {
          let x = onFulfilled(self.value);
          resolvePromise(promise2, x, resolve, reject);
        } catch(e) { reject(e); }}); }); }if (self.status == 'rejected') {
    promise2 = new Promise(function (resolve, reject) {
      setTimeout(function () {
        try {
          let x = onRejected(self.value);
          resolvePromise(promise2, x, resolve, reject);
        } catch(e) { reject(e); }}); }); }if (self.status == 'pending') {
    promise2 = new Promise(function (resolve, reject) {
      self.onResolvedCallbacks.push(function (value) {
        try {
          let x = onFulfilled(value);
          resolvePromise(promise2, x, resolve, reject);
        } catch(e) { reject(e); }}); self.onRejectedCallbacks.push(function (value) {
        try {
          let x = onRejected(value);
          resolvePromise(promise2, x, resolve, reject);
        } catch(e) { reject(e); }}); }); }return promise2;
}
Promise.prototype.catch = function (onRejected) {
  return this.then(null, onRejected);
}
Promise.all = function (promises) {
  return new Promise(function (resolve, reject) {
    let result = [];
    let count = 0;
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(function (data) {
        result[i] = data;
        if(++count == promises.length) { resolve(result); }},function (err) { reject(err); }); }}); }Promise.deferred = Promise.defer = function () {
  var defer = {};
  defer.promise = new Promise(function (resolve, reject) {
    defer.resolve = resolve;
    defer.reject = reject;
  })
  return defer;
}
/** * npm i -g promises-aplus-tests * promises-aplus-tests Promise.js */
try {
  module.exports = Promise
} catch (e) {
}

Copy the code