This article is a systematic study of the author “Javascript advanced programming” 4th edition of the notes recorded, the content is mainly biased to summary, suitable for a little basic and want to systematically study the students to read. If there is any understanding in the notes or this is not correct in the narrative, we welcome your criticism and correction. The follow-up idea is to continue to add one or two interview questions to each section. What are the classic interview questions that you are welcome to discuss and make progress together

1. JavaScript implementation

  • Core (ECMAScript) : Defined by ECMA-262 and provides core functionality.

    1. grammar
    2. type
    3. statements
    4. The keyword
    5. Reserved words
    6. The operator
    7. Global object
  • Document Object Model (DOM) : Provides methods and interfaces for interacting with web content

    1. DOM view: Describes the interface that tracks different views of a document, such as the document before and after CSS styles are applied.
    2. DOM events: Interfaces that describe events and their handling.
    3. DOM Styles: Describes the interface that handles CSS styles for elements.
    4. DOM traversal and scope: Describes the interface for traversing and manipulating the DOM tree.
  • Browser Object Model (BOM) : Provides methods and interfaces for interacting with the browser.

    1. The ability to pop up a new browser window;
    2. The ability to move, zoom, and close browser Windows;
    3. The Navigator object, which provides detailed information about the browser;
    4. Location object, which provides detailed information about the page the browser loaded;
    5. Screen object, which provides detailed information about the user’s screen resolution;
    6. Performance object that provides detailed information about browser memory usage, navigation behavior, and time statistics;
    7. Cookie support;
    8. Other custom objects, such as XMLHttpRequest and IE’s ActiveXObject.

1.1. JavaScript features

Js is an interpreted scripting language (code is not precompiled)

2, cross-platform features, under the support of most browsers, can run on a variety of platforms (such as Windows, Linux, Mac, Android, iOS, etc.).

Weakly typed scripting languages

There are no strict requirements on the data type used, and type conversion can be carried out, simple and flexible.

4. Single-threaded, event-driven

JavaScript responds to the user in an event-driven manner. The actions that occur when an operation is performed on a Web Page are called events. Pressing the mouse, moving a window, selecting a menu, etc., can all be considered events. When an event occurs, it may trigger an event response and execute some corresponding scripts. This mechanism is called “event-driven”.

5. Object oriented

An object-based scripting language, which means JavaScript can use objects it has already created. Thus, much of the functionality can come from the interaction of methods and scripts of objects in a scripting environment.

6. Security

JavaScript is a kind of security language, it does not allow access to the local hard disk, cannot store data to the server, does not allow to modify and delete network documents, only through the browser to achieve information browsing or dynamic interaction. Thus effectively prevent the loss of data.

2,<script>The element

JavaScript is inserted into an HTML page through a

  • To include an external JavaScript file, you must set the SRC property to the URL of the file to include. Files can be on the same server as web pages, or they can be in completely different domains.
  • all<script>Elements are interpreted in the order in which they appear on the page. Without using the defer and async properties, include the<script>The code in the element must be interpreted in strict order.
  • For scripts that do not delay execution, the browser must finish interpreting the location<script>Element before continuing to render the rest of the page. For this reason, it is usually appropriate to put<script>The element is placed at the end of the page, after and after the main content</body>Tag before.
  • You can use the defer attribute to defer executing the script until the document has been rendered. Deferred scripts are executed in principle in the order in which they are listed.
  • The async property can be used to indicate that scripts do not wait for other scripts and do not block document rendering, which is asynchronous loading. Asynchronous scripts are not guaranteed to be executed in the order in which they appear on the page.
  • Through the use of<noscript>Element to specify what to display when the browser does not support scripting. If the browser supports and enables scripting<noscript>Nothing in the element is rendered.

3. Language foundation

The core of any language describes how the language works at its most basic level, in terms of syntax, operators, data types, and built-in functionality on which complex solutions can be built. As mentioned earlier, ECMA-262 defines all of these aspects of JavaScript in the form of a pseudo-language called ECMAScript.

3.1, variables,

ECMAScript variables are loosely typed, meaning that variables can be used to hold any type of data. Each variable is nothing more than a named placeholder to hold arbitrary values. There are three keywords to declare variables: var, const, and let. Var is available in all versions of ECMAScript, while const and let are available only in ECMAScript 6 and later.

3.1.1. Var keyword

Var declares scope

Use the var operator to define local variables inside a function

function test({
    var message = "hi"// Local variables
}
test();
console.log(message); / / error! The message variable will be destroyed when the function exits
Copy the code

Omit the var operator when defining variables within a function

function test({
    message="hi"; // Global variables
}
test();
console.log(message); // "hi"
// Without the var operator, message becomes a global variable. This variable is defined once the test() function is called and is accessible outside the function. This is not recommended
Copy the code

Var variable promotion

Variables declared using the var keyword are automatically promoted to the top of the function scope

function foo() console.log(age); 
    var age = 26;
}

foo(); // undefined
The ECMAScript runtime treats this as equivalent to the following code
function foo() {
    var age;
    console.log(age); 
    age = 26;
}

foo(); // undefined

// This is called the "hoist", which simply pulls all variable declarations to the top of the function scope.
// In addition, it is ok to use var to declare the same variable multiple times.
Copy the code

3.1.2. Let keyword

Use rules (as opposed to VAR)

  • The scope of the let declaration is block scope, while the scope of the var declaration is function scope.
  • Redundant declarations are not allowed in the same block scope
  • Variables declared by let are not promoted in scope

Temporary dead zone

// Name will be promoted
console.log(name); // undefined
var name = 'Matt';

// age will not be promoted
console.log(age); // ReferenceError: Age is not defined
let age = 26;
Copy the code

Explanation: When parsing code, the JavaScript engine also pays attention to let declarations that appear after blocks, but undeclared variables cannot be referenced in any way before then. The moment of execution prior to a LET declaration is known as a “temporal dead zone,” where references to any variables declared later will raise a ReferenceError.

Global declarations

Unlike the var keyword, variables declared in the global scope using let do not become properties of the Window object (variables declared by var do). However, let declarations still occur in global scope.

var name = 'Matt'console.log(window.name); // 'Matt'

let age = 26;
console.log(window.age); // undefined
Copy the code

Let declaration in the for loop

Before the let, the iterated variables defined by the for loop are permeated outside the loop body, whereas after the let, the iterated variables are scoped inside the for block

for (var i = 0; i < 5; ++i) {
// loop logic
}
console.log(i); / / 5

for (let i = 0; i < 5; ++i) {
// loop logic
}

console.log(i); ReferenceError: I is not defined


Copy the code

The most common problem with var is the odd declaration and modification of iterating variables:

for (var i = 0; i < 5; ++i) { 
    setTimeout(() = > console.log(i), 0)}// 5, 5, 5, 5, 5, 5
Copy the code

This happens because when the loop exits, the iteration variable holds the value that caused the loop to exit: 5. When the timeout logic is later executed, all the I’s are the same variable, so the output is the same final value.

With let, the JavaScript engine declares a new iteration variable behind the scenes for each iteration loop. Each setTimeout references a different instance of a variable, so console.log outputs the expected value for each iteration of the variable during the loop execution.

for (let i = 0; i < 5; ++i) { 
    setTimeout(() = > console.log(i), 0)}// Outputs 0, 1, 2, 3, 4

Copy the code

This behavior of declaring one instance of an independent variable per iteration applies to all styles of for loops, including for-in and for-of.

3.1.2 const declaration

Const behaves much the same as let, with the only important differences being that variables declared with it must also be initialized, and attempts to modify a variable declared by const result in a runtime error.

const age = 26;
age = 36// TypeError: Assigns values to constants
// Const also does not allow repeated declarations

const name = 'Matt';
const name = 'Nicholas'; // SyntaxError

// The scope of const declarations is also a block
const name = 'Matt'; 
if (true) {
    const name = 'Nicholas';
}
console.log(name); // Matt
Copy the code

The restriction declared by const applies only to references to the variable to which it refers. In other words, if a const variable refers to an object, modifying properties inside that object does not violate the const constraint.

const person = {};

person.name = 'Matt'; // ok
Copy the code

The JavaScript engine creates separate instances of variables for let declarations in the for loop. Although const variables are similar to let variables, we cannot use const to declare iterating variables (because iterating variables increment) :

for (const i = 0; i < 10; ++i) {
} 
// TypeError: Assigns values to constants
Copy the code

However, if you just want to declare a for loop variable that will not be modified using const, that’s fine. That is, each iteration just creates a new variable. This makes particular sense for for-of and for-in loops:

let i = 0;
for (const j = 7; i < 5; ++i) { 
    console.log(j);    // 7, 7, 7, 7, 7
}

for (const key in {a: 1.b: 2{})console.log(key); // a, b
}

for (const value of [1.2.3.4.5]) { 
    console.log(value);  // 1, 2, 3, 4, 5
}
Copy the code

4. Data types

Simple data types (also known as primitive types) :

  • Undefined- has only one value, the special value Undefined. When a variable is declared using var or let but not initialized, it is equivalent to giving the variable a undefined value
  • Null– There is only one value, the special value Null. Logically, a null value represents an empty object pointer, which is why passing a NULL to typeof returns “object”
  • Boolean– One of the most frequently used types in ECMAScript, has two literals: true and false.
  • Number- Probably the most interesting data type in ECMAScript is Number. The Number type uses IEEE 754 format to represent integer and floating point values (also called double values in some languages). There are three functions to convert non-numeric values to numeric values: Number(), parseInt(), and parseFloat().
  • String– The data type represents zero or more sequences of 16-bit Unicode characters. Strings can be marked with double (“), single (‘), or backquotes
  • Symbol–Symbol is a new data type in ECMAScript 6. Symbols are primitive values, and symbol instances are unique and immutable. The purpose of the symbol is to ensure that object attributes are uniquely identified without the risk of attribute collisions.

Complex data types (also known as reference types) :

  • Object — An Object in ECMAScript is simply a collection of data and functionality. Objects are created by the new operator followed by the name of the object type. Developers can create their own objects by creating instances of type Object and then adding properties and methods to the objects
    1. Constructor: The function used to create the current object. In the previous example, the value of this property was the Object() function.
    2. hasOwnProperty(propertyName) : Used to determine whether a given attribute exists on the current object instance (not the stereotype). The property name to be checked must be a string (such as O.hasownProperty (“name”)) or a symbol.
    3. isPrototypeOf(object) : Used to determine whether the current object is a prototype of another object. (Chapter 8 covers prototypes in more detail.)
    4. propertyIsEnumerable(propertyName) : Used to determine whether a given attribute can be enumerated with a for-in statement (discussed later in this chapter). As with hasOwnProperty(), the property name must be a string.
    5. ToLocaleString () : Returns a string representation of an object that reflects its localized execution environment.
    6. ToString () : Returns a string representation of an object.
    7. ValueOf () : Returns the string, numeric, or Boolean representation of an object. Usually the same as the return value of toString().

4.1,nullandundefinedWhat’s the difference? (Interview questions)

Undefined has only one value, which is the special value undefined. When a variable is declared using var or let but not initialized, it is equivalent to assigning a value of undefined, which is a false value

let message; // This variable is declared with undefined
// age is not declared
if (message) {
    // This block will not execute
}
if(! message) {// This block will execute
}
if (age) {
    // There will be an error
}
Copy the code

The Null type also has only one value, the special value Null. Logically, null represents an empty object pointer, which is why passing a null to typeOF returns “object”. Undefined is derived from null, so ecMA-262 defines them as ostensibly equal, as shown in the following example:

console.log(null= =undefined); // true
console.log(null= = =undefined); // false
Copy the code

4.2. Typeof operator

let message = "some string"console.log(typeof message); // "string"
console.log(typeof(message)); // "string"
console.log(typeof 95); // "number"
Copy the code
  • “Undefined” indicates undefined value;
  • “Boolean” indicates that the value is Boolean;
  • “String” indicates that the value is a string;
  • “Number” indicates a numerical value.
  • “Object” indicates that the value is an object (not a function) or null;
  • “Function” means the value is a function;
  • “Symbol” means the value is a symbol.

Variables, scope, and memory

5.1. Original and reference Values

ECMAScript variables can contain two different types of data: raw and reference values. Primitive values are the simplest data, and reference values are objects made up of multiple values.

When assigning a value to a variable, the JavaScript engine must determine whether the value is a primitive or a reference value. The previous chapter discussed six primitive values: Undefined, Null, Boolean, Number, String, and Symbol. A variable that holds the original value is accessed by value because we are manipulating the actual value stored in the variable.

Suppose you have the following basic types of variables:

var name = 'jozo'; \var city = 'guangzhou'; \var age = 22; \Copy the code

Then its storage structure is shown as follows:

A reference value is an object held in memory. Unlike other languages, JavaScript does not allow direct access to memory locations, so you cannot directly manipulate the memory space in which an object resides. When you manipulate an object, you are actually manipulating a reference to the object rather than the actual object itself. To do this, the variable holding the reference value is accessed by reference.

Suppose there are the following objects:

var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};
Copy the code

Then its storage structure is shown as follows:



5.2. Copy Values

When assigning an original value from a variable to another variable, the original value is copied to the location of the new variable. Look at the following example:

let num1 = 5let num2 = num1;
Copy the code

When a reference value is assigned from one variable to another, the value stored in the variable is copied to the location of the new variable. The difference here is that the copied value is actually a pointer to an object stored in heap memory. After the operation is complete, both variables actually point to the same object, so changes on one object are reflected on the other, as shown in the following example:

let obj1 = new Object(a);let obj2 = obj1;

obj1.name = "Nicholas";

console.log(obj2.name); // "Nicholas"
Copy the code

5.2.1. Assignment, Deep copy and shallow copy

When we assign an object to a new variable, we assign the object’s address on the stack, not the data in the heap. That is, two objects point to the same storage space. If any object is changed, it is the content of the changed storage space. Therefore, the two objects are linked.

let  obj1 = {nameZhang SAN, Age:12}
letObj2 = obj1 obj2. name = 'li' console. log(obj1)// {name: 'li', age:12}
var a = [1.2.3.4];
var b = a; a[0] = 0;
console.log(a,b); / / [0, 2, 3, 4], [0, 2, 3, 4]
Copy the code

Shallow copy Creates memory in the heap again. The basic data types of objects before and after the shallow copy do not affect each other. However, the reference types of objects before and after the shallow copy affect each other because they share the same memory block.

  • Object.assign()*

The object.assign () method copies the enumerable properties of any number of source objects to the target Object and returns the target Object.

let obj1 = { person: {name: "Zhang".age: 41},sports:'basketball' };
let obj2 = Object.assign({}, obj1);
obj2.person.name = "Bill";
obj2.sports = 'football'
console.log(obj1); // {person: {name: "李四", age: 41}, sports: 'basketball'}
Copy the code
  • Expansion operator… *

The expansion operator is an ES6 / ES2015 feature that provides a very convenient way to perform shallow copies, the same functionality as object.assign ().

let obj1 = { nameZhang SAN,address: {x:100.y:100}}
let obj2= {... obj1}
obj1.address.x = 200;
obj1.name = 'bill'
console.log('obj2',obj2) // obj2 {name: 'zhang3 ', address: {x: 200, y: 100}}

Copy the code
  • Array.prototype.concat()*
let arr = [1.3, {username: 'Joe'}];
let arr2 = arr.concat();    
arr2[2].username = 'bill';
console.log(arr);

//[1, 3, {username: 'id'}]

Copy the code
  • Array.prototype.slice()*
let arr = [1.3, {username: ' 张三' }];

let arr3 = arr.slice();

arr3[2].username = 'bill'

console.log(arr); // [1, 3, {username: 'id'}]
Copy the code

Deep copy

Create a new area of heap memory to store the new object, and make a recursive copy of the child objects in the object. The two objects before and after the copy do not affect each other.

  • JSON.parse(JSON.stringify())*

Json.stringify converts an object into a JSON string, and json.parse parses the string into an object. As it goes, new objects are created, and the object opens up a new stack for deep copy.

let arr = [1.3, {username: ' 张三'}];

let arr4 = JSON.parse(JSON.stringify(arr));

arr4[2].username = 'duncan';
Copy the code

This method can do deep copies of arrays or objects, but it can’t handle functions and regees, because when these are processed based on json.stringify and json.parse, the resulting re is no longer a re (becomes an empty object) and the resulting function is no longer a function (becomes null).

  • recursive

The recursive method implements the principle of deep cloning: iterating through objects and arrays until they contain all the basic data types, and then copying, which is called deep copy.

function deepClone(obj, hash = new WeakMap(a)) {

    // If it is null or undefined, I will not copy it

    if (obj === null) return obj;  

    if (obj instanceof Date) return new Date(obj);

    // May be objects or ordinary values if functions do not need deep copies

    if (obj instanceof RegExp) return new RegExp(obj);

    // Make a deep copy of an object

    if (typeofobj ! = ="object") return obj;

    if (hash.get(obj)) return hash.get(obj);

    // Find the constructor from the parent class stereotype, which points to the current class itself

    let cloneObj = new obj.constructor();

    hash.set(obj, cloneObj);

    for (let key in obj) {

        if (obj.hasOwnProperty(key)) {

         // Implement a recursive copycloneObj[key] = deepClone(obj[key], hash); }}return cloneObj;

}

let obj = { name: 1.address: { x: 100}}; obj.o = obj;// The object has a circular reference

let d = deepClone(obj);

obj.address.x = 200; 
console.log(d); // { name: 1, address: { x: 200 } }
Copy the code

5.3. Determine the type

The Typeof operator mentioned in the previous chapter is best used to determine whether a variable is primitive. More specifically, it is the best way to determine whether a variable is a string, value, Boolean, or undefined. If the value is an object or NULL, then typeof returns “object”, as shown in the following example:

let s = "Nicholas"let b = true;

let i = 22let u;

let n = null;

let o = new Object(a);console.log(typeof s); // string
console.log(typeof i); // number
console.log(typeof b); // boolean
console.log(typeof u); // undefined
console.log(typeof n); // object
console.log(typeof o); // object
Copy the code

While typeof is useful for raw values, it is less useful for reference values. We usually don’t care if a value is an object, but rather what kind of object it is. To solve this problem, ECMAScript provides the instanceof operator with the following syntax:

result = variable instanceof constructor

The instanceof operator returns true if the variable is an instanceof a given reference type (as determined by its stereotype chain, more on in chapter 8). Consider the following example:

console.log(person instanceof Object); 
// Is the person variable Object?
console.log(colors instanceof Array); 
// Is the variable colors Array?
console.log(pattern instanceof RegExp); 
// Is the variable pattern RegExp?
Copy the code

By definition, all reference values are instances of Object, so detecting any reference values and Object constructors through the instanceof operator returns true. Similarly, if instanceof is used to detect the original value, false will always be returned because the original value is not an object.

5.4. Scope

Any variable (whether it contains a raw value or a reference value) exists in some execution context (also known as scope). This context (scope) determines the lifetime of variables and what parts of the code they can access. The execution context can be summarized as follows.

  • Execution context is divided into global context, function context and block-level context.
  • Each time the code execution flow enters a new context, a chain of scopes is created to search for variables and functions.
  • The local context of a function or block can access variables not only in its own scope, but also in any containing context or even in the global context.
  • The global context can only access variables and functions in the global context, and cannot directly access any data in the local context.
  • The execution context of a variable is used to determine when memory is freed.

Rounding a

var color = "blue";

function changeColor() if (color === "blue") {
        color = "red";

        } else {

        color = "blue";
    }
}
changeColor();
Copy the code

For this example, the scope chain of the function changeColor() contains two objects: its own variable object (the one that defines the arguments object) and a variable object for the global context. The variable color is accessible inside the function because it can be found in the scope chain.

Rounding out the second

var color = "blue";
function changeColor() let anotherColor = "red";
    function swapColors({
        let tempColor = anotherColor; 
        anotherColor = color;
        color = tempColor;
        // Here you can access color, anotherColor, and tempColor

    }
    // We can access color and anotherColor, but not tempColor swapColors();

}
// Only color can be accessed here
changeColor();
Copy the code

The above code involves three contexts: the global context, the local context of changeColor(), and the local context of swapColors(). There is a variable color and a function changeColor() in the global context. The local context of changeColor() has a variable anotherColor and a function swapColors(), but the variable color in the global context is accessible here. The local context of swapColors() has a variable tempColor that can only be accessed in this context. Neither the global context nor the local context of changeColor() is accessible to tempColor. In swapColors(), you can access variables in the other two contexts because they are parent contexts.

5.4.1 Scope (variable promotion, function promotion, and temporary dead zone)

So, what does variable promotion look like?

console.log(a);
var a = 10;
Copy the code

In this script, undefined is printed. Why?

var a;
console.log(10);
a = 10;
Copy the code

If you look at the code above, during JavaScript parsing, a will be extracted and declared above. When console.log(a) is printed, it is undefined because A declared it but did not fill in the value. What if this code were a let or const statement? There will be a temporary dead zone.

console.log(a);
let a = 10;
Copy the code

Output:

VM196:1 Uncaught ReferenceError: Cannot access 'a' before initialization
Copy the code

OK, a brief summary of variable promotion and temporary dead zones:

  • Print in front of the variable defined by var, because the variable is promoted, so you can print undefined
  • Print before a variable defined by let, const, because of a temporary dead zone problem.

Now look at function promotion:

var foo = 3; function getFoo() { var foo = foo || 5; console.log(foo); 5} getFoo();Copy the code

Remember one sentence:

  • The function is a first-class citizen

So, in the above code, JavaScript parsing would become:

function getFoo() {
  var foo;
  foo = foo || 5;
  console.log(foo);
}
var foo;
foo = 3;
getFoo();
Copy the code

See, this is function promotion.

5.5. Interview questions related to variable promotion

Title 1

function getFoo() {
  foo();
  var foo = function() {
    console.log(1);
  }
  foo();
  function foo() {
    console.log(2);
  }

  foo();
}
getFoo();
// 2
// 1
// 1
Copy the code

If we change it into variables and functions, we can know the effect after the promotion:

function getFoo() {
  var foo;

  function foo() {
    console.log(2);
  }

  foo(); // 2

  foo = function() {
    console.log(1);
  }

  foo(); // 1

  foo(); // 1
}
getFoo();
Copy the code

Topic 2

console.log(a);

var a = 10;
var a = 100;

console.log(a);

function a() {
  console.log('a');
}
function a() {
  console.log('aa');
}

a();

// f a() { console.log('aa')}
// 100
// a is not a function

Copy the code

Topic 3

var a = 1; function b() { a = 10; return; function a() {} } b(); console.log(a); / / 1Copy the code

Topic 4

function foo() { function bar() { return 3; } return bar(); function bar() { return 8; } } console.log(foo()); / / 8Copy the code

Topic 5

var foo = { n: 1 };

(function(foo) {
  console.log(foo.n);
  foo.n = 3;
  foo = { n: 2 };
  console.log(foo.n);
})(foo)

console.log(foo.n);
Copy the code

The answer:

var foo = { n: 1 }; (function(foo){// The parameter foo refers to the same memory space as the argument foo, in which n is 1 var foo; // The priority is lower than the parameter, invalid. console.log(foo.n); // output 1 foo.n = 3; Foo = {n: 2}; foo = {n: 2}; // The parameter foo refers to the new memory space, where n is 2.console.log (foo.n); // Print the value of n for the new memory space})(foo); console.log(foo.n); // The argument foo refers to the same memory space, where n is 3.Copy the code

Topic 6. Talk about the understanding of scope chains

A: When the code in the context executes, it creates a scope chain for the variable object. This scope chain determines the order in which the code at each level of context accesses variables and functions. The variable object of the context in which the code is executing is always at the front of the scope chain. If the context is a function, its active object is used as a variable object. Active objects initially have only one definition variable: arguments. The next variable object in the scope chain comes from the containing context, the next object comes from the containing context, and so on up to the global context; The variable object of the global context is always the last variable object of the scope.

As mentioned in JavaScript In-depth variable Objects, when searching for a variable, it will first search from the variable object of the current context. If it is not found, it will search from the variable object of the parent (lexical level of the parent) of the execution context until it finds the variable object of the global context, that is, the global object. Thus a linked list of variable objects in multiple execution contexts is called a scoped chain.

Objects, classes, and object-oriented programming

6.1. Create an object

While it is easy to create objects using Object constructors or Object literals, these methods have a significant disadvantage: creating multiple objects with the same interface requires a lot of repetitive code.

6.1.1. Factory Mode

The factory pattern is a well-known design pattern widely used in software engineering to abstract the process of creating specific objects.

function createPerson(name, age, job) {
    let o = new Object(a); o.name = name; o.age = age; o.job = job; o.sayName =function() {
        console.log(this.name);
    };
    return o;
}

let person1 = createPerson("Nicholas".29."Software Engineer");

let person2 = createPerson("Greg".27."Doctor");
Copy the code

Here, the function createPerson() takes three parameters from which an object containing The Person information is built. This function can be called multiple times with different arguments, each time returning an object containing three properties and one method.

6.1.2. Constructor schema

Native constructors such as Object and Array can be used directly by the runtime in the execution environment. You can also customize constructors that define properties and methods for your own object types in the form of functions.

function Person(name, age, job)this.name = name;
    this.age = age; 
    this.job = job;
    this.sayName = function(console.log(this.name);
    };
} 

let person1 = new Person("Nicholas".29."Software Engineer"); 
let person2 = new Person("Greg".27."Doctor");

person1.sayName(); // Nicholas
person2.sayName(); // Greg
Copy the code

In this example, the Person() constructor replaces the createPerson() factory function. In fact, the code inside Person() is basically the same as that inside createPerson(), with the following differences.

  • No object is explicitly created.
  • Properties and methods are assigned directly to this.
  • There is no return.

6.1.3 Prototype mode

Each function creates a Prototype property, which is an object containing properties and methods that should be shared by instances of a particular reference type. In effect, this object is a prototype of the object created by calling the constructor. The advantage of using a stereotype object is that the properties and methods defined on it can be shared by the object instance. Values that were originally assigned directly to object instances in constructors can be assigned directly to their prototypes, as follows:

function Person({}

Person.prototype.name = "Nicholas"; 
Person.prototype.age = 29; 
Person.prototype.job = "Software Engineer"; 
Person.prototype.sayName = function({
    console.log(this.name);
};

let person1 = new Person(); 
person1.sayName(); // "Nicholas"
let person2 = new Person(); 
person2.sayName(); // "Nicholas"

console.log(person1.sayName == person2.sayName); // true
Copy the code

Here, all the attributes and the sayName() method are added directly to the Person prototype property; there is nothing in the constructor body. But after this definition, the new object created by calling the constructor still has the corresponding properties and methods. Unlike the constructor pattern, the properties and methods defined using this stereotype pattern are shared by all instances. Thus person1 and person2 access the same attributes and the same sayName() function.

6.2 Prototype chain

Stereotype chains are defined as ECMAScript’s main inheritance method. The basic idea is to inherit properties and methods of multiple reference types through stereotypes. Review the relationship between constructors, stereotypes, and instances: each constructor has a stereotype object, the stereotype has a property that points back to the constructor, and the instance has an internal pointer to the stereotype. What if the stereotype is an instance of another type? That means that the stereotype itself has an internal pointer to another stereotype, which in turn has a pointer to another constructor. This creates a chain of stereotypes between the instance and the stereotype. This is the basic idea of a prototype chain.

Implementing the prototype chain involves the following code pattern:function SuperType() this.property = true;
}

SuperType.prototype.getSuperValue = function(return this.property;

};

function SubType() this.subproperty = false;

}


/ / inherit the SuperType

SubType.prototype = new SuperType(); 
SubType.prototype.getSubValue = function ({
    return this.subproperty;
};

 
let instance = new SubType(); 
console.log(instance.getSuperValue()); // true
Copy the code

7, functions,

7.1 function expressions, function declarations, and arrow functions

Functions are one of the most interesting parts of ECMAScript, mainly because functions are actually objects. Each Function is an instance of Function, which has properties and methods, just like any other reference type. Because functions are objects, function names are Pointers to function objects and are not necessarily bound to the function itself

Definition of how a function is declared

function sum (num1, num2return num1 + num2;
}
Copy the code

Before any code executes, the JavaScript engine reads the function declaration and generates the function definition in the execution context. A function expression, on the other hand, must wait until the code executes to its line before generating the function definition in the execution context. Consider the following example:

// no problem console.log(sum(10,10));

 function sum(num1, num2{

    return num1 + num2;

}
Copy the code

The above code works because the function declaration is read and added to the execution context before any code is executed. This process is called function declaration promotion.

Functional expression


sum(1.2) //// Error! function doesn't exist yet
let sum = function(num1, num2return num1 + num2;
};

sum(1.2) / / 3

sum2(1.2) //3 Because the JavaScript engine reads the function declaration first and then executes the code
function sum2(num1, num2{
    return num1 + num2;
}

Copy the code

Arrow function

let sum = (num1, num2) = > { 
    return num1 + num2;
};
Copy the code

Arrow functions cannot use arguments, new.target, and

Super also cannot be used as a constructor. In addition, the arrow function has no Prototype attribute.

The arrow function this points to the rule:

  • Arrow function doesn’t have anyprototype(prototype), so the arrow function itself does not have this
  • The arrow function’s this points to this, which inherits from the first normal function in the outer layer when it is defined.
  • The arrow function’s this pointer cannot be modified directly
  • The arrow function has no normal function outside, and its this points to both strict and non-strict modeswindow(Global object)

7.2, this

Another special object is this, which behaves differently in standard and arrow functions.

In standard functions, this refers to the context object that treats the function as a method call, and is usually referred to as this (this points to Windows when a function is called in the global context of a web page). Consider the following example:

window.color = 'red'let o = {
    color'blue'
};

function sayColor() console.log(this.color);
}

sayColor(); // 'red'


o.sayColor = sayColor; 
o.sayColor(); // 'blue'
Copy the code

In arrow functions, this refers to the context in which the arrow function is defined. The following example demonstrates this. In both calls to sayColor(), this refers to the window object because the arrow function is defined in the window context:

window.color = 'red'let o = {
    color'blue'
};

let sayColor = () = > console.log(this.color); 
sayColor(); // 'red'

o.sayColor = sayColor; o.sayColor(); // 'red'
Copy the code

7.3, the recursion

Recursive functions usually take the form of a function calling itself by name, as shown in the following example:

    function factorial(numif (num <= 1) {
            return 1;
        } else {
            return num * factorial(num - 1); }}Copy the code

This is a classic recursive factorial function. This is fine, but if you assign this function to another variable, you get a problem:

let anotherFactorial = factorial; 
factorial = null;
console.log(anotherFactorial(4)); / / an error
Copy the code

Code running in strict mode cannot access arguments.callee because accessing it will cause an error. In this case, you can use named function expression for this purpose. Such as:

const factorial = (function f(numif (num <= 1) {
        return 1;
    } else {
        return num * f(num - 1); }});Copy the code

Here we create a named function expression f() and assign it to the variable factorial. Even if a function is assigned to another variable, the name f of the function expression remains the same, so recursive calls are not a problem. This mode can be used in both strict and non-strict modes.

8. Asynchronous programming

8.1, synchronization,

Synchronous behavior corresponds to sequential execution of processor instructions in memory. Each instruction is executed in the exact order in which it appears, and each instruction is immediately followed by information stored locally in the system (such as registers or system memory).

8.2, asynchronous

Asynchronous behavior is similar to a system interrupt, where an entity outside the current process can trigger code execution. Asynchronous operations are often required because it is usually not feasible to force a process to wait for a long operation (synchronous operations must wait). Long waits can occur if the code accesses resources with high latency, such as sending a request to a remote server and waiting for a response.

8.2.1. The previous asynchronous programming mode

In the early days of JavaScript, only callback functions were supported to indicate asynchronous completion. Concatenating multiple asynchronous operations is a common problem that often requires deeply nested callback functions (colloquially called “callback hell”) to solve.

1. Asynchronous return value

function double(value,callback) {
    setTimeout(() = > callback(value * 2),100)
}

double(3.(x) = > console.log(x)) // 6 (about 1000 ms later)
Copy the code

2. Nested asynchronous callback

The callback situation is further complicated if the asynchronous return value depends on another asynchronous return value. In real code, this would require nested callbacks:

function  double(value, success, failure) {
    setTimeout(() = >{
        try{
            if(typeof! = ='number') {
                throw 'Must provide number as first argument'
            }
            sucess(value * 2)}catch (e) {
            failure(e)
        }
    },1000)}const successCallback = (x) = > {

    double(x, (y) = > console.log(`Success: ${y}`));

};

const failureCallback = (e) = > console.log(`Failure: ${e}`);

double(3, successCallback, failureCallback);

// Success: 12 (about 1000 ms later)
Copy the code

Obviously, as the code gets more complex, the callback strategy is not extensible. The term “callback hell” is aptly named. Nested callback code is a nightmare to maintain.

8.2.2, futures

I. Basis of the contract

1. Three states of contract

Pending is the initial state of a contract. In the undecided state, an appointment can be settled, which is a pity (settled) state, or rejected (resolved) state. No matter which state you settle in, it’s irreversible.

2. Control the contract state by executing functions

Because the state of the contract is private, it can only be manipulated internally. The internal operation is done in the executive function of the contract. The executor function has two primary responsibilities: initializing the asynchronous behavior of the contract and controlling the final transition of state.

Example 1 (Order of execution)new Promise(() = > setTimeout(console.log, 0.'executor')); 
setTimeout(console.log, 0.'promise initialized');
// executor
// promise initializedExample 2 (Delayed switching state)let p = new Promise((resolve, reject) = > setTimeout(resolve, 1000));
// The timeout callback (resolve()) will not be executed when console.log prints the scheduled instance.
setTimeout(console.log, 0, p); // Promise <pending>Example 3 (State irreversible)let p = new Promise((resolve, reject) = > {
    resolve();
    reject(); // No effect
});

setTimeout(console.log, 0, p);  
// Promise <resolved>
Copy the code

3, Promise. Resolve ()

Contracts do not have to be in a pending state to begin with and then converted to a settled state by an executor function. A resolved term can be instantiated by calling the promise.resolve () static method.

Example 1 (Period conversion)setTimeout(console.log, 0.Promise.resolve());
// Promise 
      
       : undefined
      
setTimeout(console.log, 0.Promise.resolve(3));
// Promise <resolved>: 3

// Superfluous arguments are ignored
setTimeout(console.log, 0.Promise.resolve(4.5.6));
// Promise <resolved>: 4Example 2 (Idempotent method)let p = Promise.resolve(7);
setTimeout(console.log, 0, p === Promise.resolve(p));
// true
setTimeout(console.log, 0, p === Promise.resolve(Promise.resolve(p)));
// true
Copy the code

Second, the instance method of contract

1, Promise. Prototype. Then ()

Promise.prototype.then() is the primary method for adding handlers to contract instances. The then() method takes up to two arguments: the onResolved handler and the onRejected handler. Both parameters are optional and, if provided, will be executed when the contract enters the “cash” and “reject” states, respectively.

function onResolved(id) setTimeout(console.log, 0, id, 'resolved');
}

function onRejected(id) setTimeout(console.log, 0, id, 'rejected');
}

let p1 = new Promise((resolve, reject) = > setTimeout(resolve, 3000)); 
let p2 = new Promise((resolve, reject) = > setTimeout(reject, 3000));

p1.then(() = >onResolved('p1'),() = >onRejected('p1'));
p2.then(() = >onResolved('p2'),() = >onRejected('p2'));

// (3 seconds later)
// p1 resolved
// p2 rejected
Copy the code

2, Promise. Prototype. The catch ()

The promise.prototype.catch () method is used to add a rejection handler to the contract. This method accepts only one parameter: the onRejected handler. In fact, this method is a syntactic sugar; calling it is equivalent to calling promise.prototype. then(null, onRejected)

let p = Promise.reject();
let onRejected = function(e) setTimeout(console.log, 0.'rejected');
};

// The two ways to add rejection handlers are the same:
p.then(null, onRejected); // rejected
p.catch(onRejected);//rejected
Promise.prototype.catch() returns a new contract instance:let p1 = new Promise(() = > {});
let p2=p1.catch

setTimeout(console.log, 0, p1); // Promise 
      
setTimeout(console.log, 0, p2); // Promise <pending>
setTimeout(console.log,0,p1 ===p2); // false
Copy the code

3, Promise. Prototype. Finally ()

Promise. Prototype. Finally add () method is used to issue about onFinally handler, the handler in the futures will perform when converted to solve or reject status. This method avoids redundant code in the onResolved and onRejected handlers. But the onFinally handler has no way of knowing whether the date status is resolved or rejected, so this method is mostly used to add cleanup code

4. Pass resolution values and rejection reasons

let p1 = new Promise((resolve, reject) = > resolve('foo')); 
p1.then((value) = > console.log(value)); // foo
let p2 = new Promise((resolve, reject) = > reject('bar')); 
p2.catch((reason) = > console.log(reason)); // bar


let p3 = Promise.resolve('foo');
p3.then((value) = > console.log(value)); // foo
let p4 = Promise.reject('bar');
p4.catch((reason) = > console.log(reason)); // bar
Copy the code

3. Term contract linkage and term contract synthesis

First, contract chain

Concatenating schedules one by one is a very useful programming pattern. This is possible because the methods of each contract instance (then(), catch(), and finally()) return a new contract object, which in turn has its own instance method. In this way, concatenated method calls can form what is called a “contract chain.”

Example 1 (Serial synchronization task)let p = new Promise((resolve, reject) = > { console.log('first');
    resolve();
});
p.then(() = > console.log('second'))
.then(() = > console.log('third'))
.then(() = > console.log('fourth'));
// first
// second
// third
// fourth
// This implementation ends up performing a series of synchronization tasksExample 2 (Serializing asynchronous tasks)let p1 = new Promise((resolve, reject) = > { 
        console.log('p1 executor');
        setTimeout(resolve,1000)
    })
    
    p1.then(() = >new Promise((resolve, reject) = > { 
        console.log('p2 executor');
        setTimeout(resolve,1000)
    })))
    .then(() = >new Promise((resolve, reject) = > { 
        console.log('p3 executor');
        setTimeout(resolve,1000)
    }))
    .then(() = >new Promise((resolve, reject) = > { 
        console.log('p4 executor');
        setTimeout(resolve,1000)}))// p1 executor (1 second later)
// p2 executor (2 seconds later)
// p3 executor (3 seconds later)
// p4 executor (4 seconds later)
Copy the code

2. Schedule chart

Because a term can have any number of handlers, term chaining can build the structure of a directed acyclic graph. In this way, each contract is a node in the graph, and the handlers added using the instance method are directed vertices. Because each node in the diagram waits for the previous node to settle, the direction of the diagram is the order in which contracts are resolved or rejected.

// A

/ / / /

// B C

/ / / \ \

// D E F G

 

let A = new Promise((resolve, reject) = > { console.log('A');
    resolve();
});
let B = A.then(() = > console.log('B'));
let C = A.then(() = > console.log('C'));
B.then(() = > console.log('D'));
B.then(() = > console.log('E'));
C.then(() = > console.log('F'));
C.then(() = > console.log('G'));
// A
// B
// C
// D
// E
// F
// G
Copy the code

Note that the output statement of the log is a sequential traversal of the binary tree. As mentioned earlier, the contract handlers are executed in the order they were added. Because the handlers of a contract are added to the message queue before being executed one by one, a hierarchical traversal is formed.

8.2.2 asynchronous functions

ES8’s Async /await is designed to address the problem of organizing code with asynchronous structures. To do this, ECMAScript extends the function by adding two new keywords: async and await. Asynchronous functions are the result of applying a term to a JavaScript function. Asynchronous functions can suspend execution without blocking the main thread. Asynchronous functions are very handy whether you’re writing period-based code or organizing asynchronous code that executes serially or in parallel. Asynchronous functions are arguably one of the most important tools in the modern JavaScript toolkit.

A, async

Example 1 (Declaring an asynchronous function)async function foo() {}              // Function declaration
const bar = async function () {}     // Function expression
const baz = async() = > {}// Arrow functionExample 2 (Order of execution)async function foo(console.log(1);
}
foo();
console.log(2);
/ / 1
/ / 2
// Use the async keyword to make functions asynchronous, but overall the code is still evaluated synchronouslyExample 3 (return of an asynchronous function)async function foo(console.log(1);
    return 3
}
// Add a resolution handler to the returned contract
foo().then(console.log);
console.log(2);
/ / 1
/ / 2
/ / 3Of course, returning a contract object directly is also the same:async function foo(console.log(1);
    return Promise.resolve(3);
}
// Add a resolution handler to the returned contract
foo().then(console.log); 
console.log(2);
/ / 1
/ / 2
/ / 3

Copy the code

2, await

Because asynchronous functions are primarily for tasks that do not complete immediately, the ability to pause and resume execution is naturally required. Use the await keyword to suspend the execution of asynchronous function code and the wait period is resolved.

A (awaitThe use of)// Print "foo" asynchronously

async function foo({
    console.log( await Promise.resolve('foo'));
}
foo();
// foo

// asynchronously print "bar"
async function bar({
    return await Promise.resolve('bar');
}
bar().then(console.log);
// bar

// Print "baz" asynchronously after 1000 ms
async function baz({
    await new Promise((resolve, reject) = > setTimeout(resolve, 1000)); 
    console.log('baz');
}
baz();
// baz (1000 milliseconds later)
Copy the code

3. Stop and resume execution

To fully understand the await keyword, you must know that it is not as simple as waiting for a value to be available. The JavaScript runtime records where execution is paused when it encounters the await keyword. When the value to the right of the await is available, the JavaScript runtime pushes a task to the message queue that resumes the execution of the asynchronous function. Thus, even if await is followed by an immediately available value, the rest of the function is evaluated asynchronously.

async function foo() {
    console.log(2)
    await 1
    console.log(4)}console.log(1)
foo()
console.log(3) (1print1; (2) call the asynchronous function foo(); (3) (in foo()) print2; (4(in foo())awaitKeyword suspends execution for immediately available valuesnullAdd a task to the message queue; (5) foo() exits; (6print3; (7) the code of the synchronized thread completes execution; (8) the JavaScript runtime retrieves the task from the message queue and resumes asynchronous function execution; (9) (in foo()) resume execution,awaitachieve1Value (not used here); (10) (in foo()) print4; (11) foo() returns.Copy the code

9. Event Loop

9.1 micro-task and Macro-task

  • Common macro-tasks include setTimeout, setInterval, setImmediate, Script, I/O, UI rendering, etc.
  • Common micro-tasks such as process.nexttick, New Promise().then(callback),

9.1 Event Loop execution process is as follows:

  1. Initially the entire script script is executed as a macro task
  2. During the execution, the synchronous code is executed directly. During the execution, the system determines whether it is a synchronous task or an asynchronous task. New macro-tasks and micro-tasks can be generated by calling some interfaces, and the macro task enters the macro task queue and the micro-task enters the micro-task queue.
  3. When a macro task is queued up, check the list of microtasks and execute them until they are all queued up. Micro-tasks, on the other hand, are executed in teams.
  4. Performs rendering of the browser UI thread.
  5. Check whether there are Web Worker tasks and execute them.
  6. After executing the macro task in this round, go back to Step 2 and repeat the process until the macro task and microtask queues are empty.

I was going to put a lot of interview questions on it, but I thought about it and wanted to fully understand it, so I highly recommend this article!!

Queues and schedules (Macros, microtasks, Queues)

10、 BOM

  • Understand the window object, the heart of the BOM
  • Control Windows and popovers
  • Get page information through the Location object
  • Use the Navigator object to learn about the browser
  • Manipulate browser history through the history object

10.1. Window objects

All properties and methods of the window object are global, and the window can be omitted when used. All global variables are properties of the window object and all global functions are methods of the window object

var age = 29;
var sayAge = () = > alert(this.age); 
alert(window.age); / / 29
sayAge(); / / 29
window.sayAge(); / / 29
Copy the code

Three dialog boxes:

  • Alert () alert box
  • Prompt () pops up the input box. Click OK to return the input. Click Cancel to return null
  • Confirm () pops up the confirmation box. Click OK to return True. Click Cancel to return false

A pop-up window (page jump)

  • Open (” URL “, “name”, “appearance “) This method returns the pop-up child window

  • Width height top left

  • Location Whether there is an address bar; Resizable whether the window size can be adjusted; Whether scrollbars have scrollbars; Status status bar; Titlebar titlebar; Toolbar toolbar (Compatibility)

    Yes | 1 have no | 0 means no

Two timer methods:

  • SetInterval (tasks to be executed, intervals) A timer that runs continuously is stopped using clearInterval()
  • SetTimeout A timer that executes only once clearTimeout() stops the timer

Timer features: Timers are executed asynchronously and events are also executed asynchronously

// Example 1 (after the page is opened, the pop-up advertising window will automatically close 5 seconds later)
// Give opener a click-off time
$id("btn2").onclick = function (){
    opener.close();
}
// The shutdown will be delayed for 5 seconds
setTimeout( function(){
    opener.close();
},5000)


// Example 2 (handwriting function anti-shake and throttling)

// Buffering: execute [callback] after the event is triggered for n seconds. If it is triggered again within n seconds, the time is recalculated. Executed concurrently
 function debounce(fn,delay) {
     let timer = null // Create a flag to store the return value of the timer
     return function () {
         let _this = this 
         let args = arguments
         if(timer) {
           clearTimeout(timer) // Within delay, clear the previous setTimeout
           timer = null
         }
         timer = setTimeout(function(){ // Create a new setTimeout
             fn.apply(_this,args) // Bind the function
         },delay)
     }
 }
 
// Throttling: Only one task will be executed in the specified interval.

function throttle(fn,delay) {
    let isRun = false // Define a state
    let timer 
    return function(){
        if(! isRun) {clearTimeout(timer) // Clear the setTimeout interval
            return
        }
        isRun = false
        
        timer = setTimeout(function(){ // Create a new setTimeout
             fn.apply(_this,args) // Bind the function
             isRun = true
         },delay)
    }
}




Copy the code

10.2. Location Address bar object

  • Location. href = “URL” page jump replaces the current page with the specified URL page
  • Location. href gets the path to the currently open page
  • Location. assign(” URL “) page jumps
  • Location. replace(” URL “) page jump
  • Location = “URL” The page jumps
  • Window.open () jumps to the window
  • The location.reload() page is refreshed
  • Refresh the history. The go (0)
Example 1 (Browser refreshes automatically every 3 seconds)setInterval(function(){
    location.reload()
    ducument.write(Math.random())
},3000)Copy the code

10.3, history Historical record object

  • History.go (1) forward == history.forward()
  • History.go (-1) back == history.back()
  • Refresh the history. The go (0)

10.4. Document Object Page object (key)

Document.write () The browser prints

How to find page elements:

  • Document.getelementbyid () finds page elements by ID and the result is unique
  • Document. The getElementsByTagName () according to the given tag name lookup page elements The result is a collection, using the need to use subscript
  • Document. GetElementsByClassName () according to the given name of the class To find the page elements The result is a collection of compatibility
  • Document. The getElementsByName () according to the search page elements of a given name Generally applicable to form elements The result is a collection of
  • Document.queryselector () finds elements based on a given CSS selector and the result is unique and is generally used for ID selector compatibility
  • Document.queryselector (“# ID “).className HTML tag
  • Document. QuerySelectorAll () according to the given CSS selector to find elements The result is set compatibility
  • Document. The HTML error

Summary: The result of the lookup is an array of class (pseudo-array) methods:

  • document.getElementsByTagName()
  • document.getElementsByName()
  • document.getElementsByClassName()
  • document.querySelectorAll()

10.5 Operations on page Elements (core Operations)

10.5.1 Attributes:

  • Set property: obj. Property = value
  • Get property: obj. Property
  • Get custom (non-custom) attribute values: getAttribute()
  • Set the attribute: setAttribute()
/ / a
var oImg = document.getElementsByTagName('img') [0]
alert(oImg.src)
// Use js to add custom attributes to HTML elements
oImg.setAttribute('level'.8)
console.log(oImg.getAttribute('level')) / / 8

Copy the code

10.5.2, content,

InnerHTML Operation tag; Identify HTML tags; Extension :outerHTML changes the innerText operation tag of the element itself; Text content manipulation: do not recognize HTML tags; Value Action form

** Set content ** :

  • Obj. innerHTML = “Content”
  • Obj. innerText = “Content”
  • Obj. value = “content”

Get content:

  • obj.innerHTML
  • obj.innerText
  • obj.value
Example 1 (Write people in UL10Li tag)var oUl = document.querySelector('ul')
var str = ' '
for(var i = 1; i < 10; i++){
    str += '
  • Multiple sibling elements
  • '
    } oUl.innerHTML = str Copy the code

    10.5.2, style,

    Set styles:

    • Obj. Style. Style = value; Only one style can be manipulated at a time odiv.style. color = “red”
    • Obj.style. cssText = “CSS format”
    • oDiv.style.cssText = “color:red;”
    • Obj. ClassName = “className” good reuse
    var oDiv = document.querySelector('div')
    // Get the style
    console.log(oDiv.style.color) / / inline
    console.log(window.getComputedStyle(oDiv)['width'])
    // Set the style
    oDiv.style.cssText = 'color: red; font-size:16px'
    oDiv.className = 'box'  // Add the style class name
    Copy the code

    Network requests and remote resources

    11.1, axios

    Axios is a promise based web request library that works with Node.js and browsers. It is isomorphic (that is, the same set of code can run in the browser and node.js). On the server side it uses the native Node.js HTTP module, while on the client side it uses XMLHttpRequests.

    // I'll show you how to use AxiOS and the basic configuration directly in code
    
    / / axios. Js file
    
    /*** * Add axios global configuration to create requests or new instances that can reference this file ****/
    
    import axios from 'axios' / / introduction
    
    axios.defaults.timeout = 10000 // Set to request data within 10000 milliseconds, and execute error function if no request succeeds
    axios.defaults.headers.post['Content-Type'] = 'application/json; charset=UTF-8' // The post method sets the media format type
    axios.defaults.baseURL = '/realwarehouse/v1' //proxy Proxy address
    
    const CancelSourceMap = new Map(a)// Terminate the request
    
    // Global request interceptor
    axios.interceptors.request.use(config= > {
      // Cancels the same request that is currently in progress
      const source = axios.CancelToken.source()
      config.cancelToken = source.token
      if (CancelSourceMap.has(config.url)) {
        CancelSourceMap.get(config.url).cancel('Cancel duplicate request')
        CancelSourceMap.set(config.url, source)
      } else {
        CancelSourceMap.set(config.url, source)
      }
    
      return config
    }, error= > {
      return Promise.reject(error)
    })
    
    // Global response interceptor
    axios.interceptors.response.use(
      function (res) {
        // console.log(res, 'aaaaAAAAAAAAAAAAAAAAaaaAAA Global Response interceptor res')
        // Request a local file
        if (res.config && res.config.baseURL === '/static') {
          return {
            statusCode: 200.data: res.data,
            message: 'Request successful! ',}}// This is where the returned data is processed
        if (res.data && res.data.statusCode === 200) {
          return res.data
        } else {
          if (res.data.statusCode === 401) {
            window.location.href = '/login'
          }
          return Promise.reject(res.data)
        }
      },
      function (err) {
        // console.log(err, err. Response, 'aaaaAAAAAAAAAAAAAAAAaAAA Global Response interceptor err')
        // Request processing error. Perform different operations based on the code value specified by the backend convention
        if (err && err.response) {
          switch (err.response.status) {
          case 400:
            err.message = 'Request error'
            break
          case 401:
            err.message = 'Not authorized, please log in'
            break
          case 404:
            err.message = 'Error requesting address:${err.response.config.url}`
            break
          default:}}return Promise.reject(err)
      }
    )
    export default axios
    
    // The page API processes files
    
    /**** * Description: API - Home page * Creator: ZJ ****/
    
    import axios from '@axios'
    /** ** ** */
    export const getHomeOverviewData = () = > {
      return axios({
        method: 'get'.// Request mode
        url: '/home/tab'.// Request an address})}/** * Get the list of help documents **/
    export const getHelpFileList = (data) = > {
      return axios({
        method: 'get'.url: '/home/list'.params: data  / / params refs})}/** * Get the help document *@param {object} Data < Optional > // Data requested to be passed *@param {string} Data. id< must > // Help document ID *@param {string} Data. type< must > // Help document type sqL-flinkSQL Help document template- Common SQL template **/
    export const getHelpFile = (data) = > {
      return axios({
        method: 'get'.url: '/home/help',
        data              // // body})}Copy the code

    The above is just a brief introduction to axios common methods. If you are not familiar with them, you are advised to browse the official Axios documentation

    11.2. Alternative cross-source technologies

    1. Image detection

    Image detection is one of the earliest technologies for cross-domain communication using < IMG > tags. Any page can load images across domains without worrying about restrictions, so this is the main way to track online ads. You can create images on the fly and know when a response is received through their onLoad and onError event handlers.

    let img = new Image();
    
    img.onload = img.onerror = function({ 
        alert("Done!");
    };
    
    img.src = "http://www.example.com/test?name=Nicholas";
    Copy the code

    2, the json

    JSONP calls are implemented by dynamically creating

    function handleResponse(responseconsole.log(`You're at IP address ${response.ip}, 
            which is in ${response.city}.${response.region_name}`
         );
    }
    let script = document.createElement("script");
    script.src = "http://freegeoip.net/json/?callback=handleResponse";
    document.body.insertBefore(script, document.body.firstChild);
    Copy the code

    11.3, web sockets

    The goal of the Web Socket is to achieve full-duplex, two-way communication with the server over a long-term connection.

    11.3.1、 API

    To create a new WebSocket, instantiate a WebSocket object and pass in the URL that provides the connection:

    let socket = new WebSocket("ws://www.example.com/server.php");
    // Note that the WebSocket constructor must be passed an absolute URL.
    Copy the code

    WebSocket also has a readyState property that represents the current state.

    • Websocket.opening (0) : The connection is being established.
    • Websocket.open (1) : the connection has been established.
    • Websocket.closing (2) : The connection is CLOSING.
    • Websocket.close (3) : The connection is closed.

    11.3.2 Sending and receiving data

    Send data using the send() method and pass in a string, ArrayBuffer, or Blob, as follows:

    let socket = new WebSocket("ws://www.example.com/server.php");
    
    let stringData = "Hello world!";
    let arrayBufferData = Uint8Array.from(['f'.'o'.'o']); 
    let blobData = new Blob(['f'.'o'.'o']);
    
    socket.send(stringData);
    socket.send(arrayBufferData.buffer);
    socket.send(blobData);
    Copy the code

    When the server sends a message to the client, the WebSocket object fires the Message event. This message event is similar to other messaging protocols and can be accessed via the event.data property:

    socket.onmessage = function(eventlet data = event.data;
    
        // Perform some operations on the data
    };
    Copy the code