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