1 statement

1-1 “JS functions can be declared in three ways:

(1) Function() constructor

var f =new Function()
Copy the code

(2) Function declaration

function f (){
     console.log(2);
}
Copy the code

(3) Function expression

var f = function() {
      console.log(1);  
}
Copy the code

1-2 “JS variable declaration:”

  • Variables declared by var are mounted on the window, while variables declared by let and const are not
  • Var declares variables with variable promotion, let and const do not (strictly speaking, let also exists)
  • Let and const declarations form block scopes
  • Let has a temporary dead zone
  • Const declaration must be assigned

(1) Variables declared by var and const do not mount on window:

var a = 100;
console.log(a,window.a);    // 100 100
let b = 10;
console.log(b,window.b);    // 10 undefined
const c = 1;
console.log(c,window.c);    // 1 undefined
Copy the code

(2) Var declaration variables have variable promotion, let and const do not have variable promotion

console.log(a); // undefined ===> undefined = 100; console.log(b); Let b = 10; let b = 10; console.log(c); Const c = 10; c is not defined ===> const c = 10;Copy the code

(3) Let and const declarations form block scopes

if(1){ var a = 100; let b = 10; } console.log(a); If (1){var a = 100; if(1){var a = 100; const c = 1; } console.log(a); // 100 console.log(c) // Error: c is not defined ===> Cannot find the variable CCopy the code

(4) Let and const cannot be declared in the same scope. Var can

var a = 100; console.log(a); // 100 var a = 10; console.log(a); // 10 let a = 100; let a = 10; // console error: Identifier 'a' has already been declared ===>Copy the code

(5) Temporary dead zone

var a = 100; if(1){ a = 10; let a = 1; // If a is declared as let/const in the current block scope, assigning a value of 10 to a will only look for variable A in the current scope. So console Error:a is not defined // let and const are not declared in advance}Copy the code

(6) const

Once an assignment is declared, null placeholders cannot be used. Const a = 100; const a = 100; const list = []; list[0] = 10; The console. The log (list); // [10] const obj = {a:100}; obj.name = 'apple'; obj.a = 10000; The console. The log (obj); // {a:10000,name:'apple'}Copy the code

1-3 Why do JS carry out variable promotion

The underlying causes of variable declaration enhancement are:

The JS engine has a parsing process before the code is executed, creating the execution context and initializing some objects that need to be used during the code execution.

When access to a variable to the current execution context to look up the scope chain, and the first end of the scope chain point to is the variable object of the current execution context, the variable object is an attribute of the execution context, which contains the function parameter, all function and variable declarations, the object is created when the code parsing.

First of all, when JS gets a variable or a function, there will be two steps, namely parsing and execution.

In the parsing phase, JS checks the syntax and precompiles the function. Parsing will first create a global execution context, the first code to be executed in the variable, function declaration are taken out, variable first assigned to undefined, function first declared ready to use.

Before a function is executed, a function execution context is also created, similar to the global execution context, except that the function execution context takes arguments to this, arguments, and the function.

  • Global context: variable definition, function declaration
  • Function context: variable definition, function declaration, this, arguments

In the execution phase, the code is executed in sequence.

So why do we do variable promotion? There are two main reasons:

  • To improve performance
  • Better fault tolerance
  1. To improve performance

Before the JS code is executed, it is syntax-checked and precompiled, and only once. This is done to improve performance. Without this step, the variable (function) must be reparsed every time the code is executed. This is not necessary because the code does not change.

  1. Better fault tolerance

Variable promotion can improve JS fault tolerance to some extent, see the following code:

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

These two lines of code would have reported an error if there had been no variable promotion, but because there was, the code would have executed. While this can be avoided entirely during development, sometimes the code is complex. It may be used after the definition because of negligence, so it will not affect the normal use. It works fine because of the variable promotion.

Conclusion:

  • Improved declarations during parsing and precompilation can improve performance by allowing functions to pre-allocate stack space for variables at execution time
  • Declaration promotion can also improve the fault tolerance of JS code, so that some non-standard code can be executed normally

2 Classification of data types:

2-1 Basic Types:

  • String (string) — Primitive type
  • Boolean — Primitive type
  • Number — Primitive type
  • Symbol — Primitive type
  • Null
  • Undefined – undefined
  • BigInt(the BigInt data type is intended to be a larger range of integer values than the Number data type. The accuracy is in the (2^53-1) range. BigInt(10) : 10n) ES2020

Symbol and BigInt are new data types in ES6:

  • Symbol represents a unique and immutable data type created to address possible global variable conflicts.
  • BigInt is a numeric type of data that can represent integers in any precision format. Using BigInt, you can safely store and manipulate large integers, even if the Number is outside the safe integer range that Number can represent.

Note :NaN is not a data type

typeof NaN === 'number' //true
NaN==NaN  //false
Copy the code

2-2 Object types (reference types) :

A. Built-in objects/native objects

String, Number, Boolean, Array, Date, RegExp, Math, Error, Object, Function, Global

B. Host object

  • (1) BOM objects: Window, Navigator, Screen, History, Location
  • (2) DOM objects: Document, Body, Button, Canvas, etc

C. Custom objects –(refers to objects created by users, compatibility issues need to be noted by writers)

There are several ways to create a custom object:

(1) Object direct quantity:

Var obj1 = {}; Var obj2 = {x:0, y:0}; Var obj3 = {name: 'Mary', age: 18}Copy the code

(2) Factory pattern — use functions to encapsulate the details of creating objects with specific interfaces:

function createPerson(name,age,job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    return o;
}
var person1 = createPerson('zhang',30,'java');
Copy the code

(3) Constructor mode:

function Person(name,age,job){
    this.name= name;
    this.age = age;
    this.job = job;
}
var person1 = new Person('zhang',30,'java');
Copy the code

(4) Prototype mode:

function Person(){}
Person.prototype.name = 'zhang';
Person.prototype.age = '22';
Person.prototype.job = 'html5';
var person1 = new Person();
Copy the code

2-3 Judgment of data type:

2-3-1: typeof

The Typeof operator is generally used to determine which base type a value belongs to.

Disadvantages: Inability to distinguish object types

typeof 'seymoe' // 'string' typeof true // 'boolean' typeof 10 // 'number' typeof Symbol() // 'symbol' typeof null // Undefined // 'undefined' typeof {} // 'object' typeof [] // 'object' typeof(() => {}) // 'function'Copy the code

Why typeof null is object:

When js stores variables at the bottom, it stores their type information in the lowest 1-3 bits of the variable’s machine code

  • 000: object
  • 010: floating point number
  • 100: string
  • 110: a Boolean value
  • 1: the integer

However, in the case of undefined and NULL, the information storage for these two values is a bit special.

  • Null: All machine codes are 0
  • Undefined: it is an integer of −2^30

As a result, Typeof has a problem judging null, because null is treated as an object because all machine code is zero.

The 2-3-2: instanceof

Determine object type: Tests whether the constructor’s prototype appears on the prototype chain of the object being tested.

Disadvantages: You can’t tell whether a value is an array or an ordinary object

[] instanceof Array // true ({}) instanceof Object // true (()=>{}) instanceof Function // true let arr = [] let obj = Arr instanceof Array // true arr instanceof Object // true obj instanceof Object // true __proto__ === array. prototype; Array is an Object subtype. Array.prototype.__proto__ === Object.prototype, so the Object constructor is on the prototype chain of arRCopy the code

Unable to determine the original type

console.log(true instanceof Boolean); // false console.log(undefined instanceof Object); // false console.log(arr instanceof Array); // true console.log(null instanceof Object); // false console.log({} instanceof Object); // true console.log(function(){} instanceof Function); // trueCopy the code

2-3-3: Object.prototype.toString.call()

Versatile. I can judge almost everything

Object.prototype.toString.call({})// '[object Object]'
Object.prototype.toString.call([])// '[object Array]'
Object.prototype.toString.call(() => {})// '[object Function]'
Object.prototype.toString.call('abc')// '[object String]'
Copy the code

Passing in the primitive type makes it possible to determine the result because the value is wrapped.

“So, what is a wrapped object:”

The “wrapper object” refers to the Number, String, and Boolean native objects corresponding to the numeric value, String, and Boolean values respectively. These three primitive objects can transform (wrap) the values of primitive types into objects.

Click here for details

3 JS operators:

3-1 Delete operator

The delete operator is used to delete an object property or array element, and returns true if the deletion succeeds or if the deleted target does not exist. However, not all attributes can be deleted:

  • Some built-in core and client properties cannot be removed
  • Variables declared by the var statement cannot be deleted
  • Functions defined by the function statement also cannot be deleted.

Such as:

var o = { x: 1, y: 2}; // Define an object console.log(delete o.x); // true, delete a property console.log(delete o.x); // true, nothing is done, x was deleted in the previous step console.log("x" in o); // false, this property no longer exists in the object console.log(delete o.tostring); // true, nothing is done, toString is inherited from console.log(delete 1); Var a = [1,2,3]; // Define an array console.log(delete a[2]); // true, delete the last element console.log(2 in a); // false, element 2 no longer exists in array console.log(a.length); Console. log(a[2]); // undefined, element 2 is empty console.log(delete a); Function f(args){} // Define a function console.log(delete f); // false, functions declared by the function statement cannot be deletedCopy the code

The 3-2 void operator

The void operator can be applied to expressions of any table type, and the expression is executed, but the result is ignored and undefined is returned.

Such as:

void 0; void "you are useless?" ; void false; void []; void /(useless)/ig; void function(){ console.log("you are so useless?" ); } void alert(1) // always return undefinedCopy the code

3-3 ++ — operator

The increment and decrement operators, borrowed from C, are pre-type and post-type and change the value of a variable.

Such as:

var a = 5; console.log(a++); // add table console.log(a); // 6 console.log(++a); // 7 console.log(a--); // 7 console.log(a--); // 7 console.log(a) // 6 console.log(--a); // 5 console.log(a) // 5Copy the code

Strange strange skill: the first home have a home, after the home table is not home (plus in front, itself and expression are added 1; The plus sign comes after the expression, instead of adding 1, the expression itself adds 1.

3-4 valueOf

Var a = 'hello ', b = 1, c = [], d = {}, E = function () {} Dr. AlueOf () / / 'good' b.v alueOf () / / 1 c. alueOf () / / [] d.v alueOf () / / {} e.v alueOf () / / ƒ () {}Copy the code

3-5 + and –

The “+” operator, if any of them are strings, converts them to strings and performs string concatenation

The “-” operator, which converts to a number, and the subtraction (-a, a * 1 a/1) can all be implicitly cast

[] + {}     // "[object Object]"
{} + []     // 0
1 + true    //2
1 + false   //1
Copy the code

4 memory

4-1 Execution context

When code is run, a corresponding execution environment is generated. In this environment, all variables are raised beforehand (variable promotion), some are assigned directly, some are undefined by default, and the code is executed from the top down, which is called the execution context.

“There are three execution environments” :

  • 1. Global environment: The environment that code enters first
  • 2. Function environment: The environment in which a function is executed when called
  • 3. The eval function

“Execution Context Characteristics:”

  • 1. Single-threaded, running on the main process
  • 2. Execute synchronously from top to bottom
  • 3. There is only one global context, which is ejected from the stack when the browser is closed
  • 4. There is no limit to the number of execution contexts of a function
  • 5. Each time a function is called, a new execution context is created

“Execute 3 phases:”

1. Creation phase

  • (1). Generate variable objects

  • (2). Establish scope chain

  • (3). Make sure this points to

2. Implementation phase

  • (1). Variable assignment

  • (2). Function reference

  • (3). Execute other codes

3. Destruction stage

  • (1). Exit the stack after execution and wait for the recycling to be destroyed

Click here for details

4-2 stack

“Concept:”

  • Stack: The stack will automatically allocate memory space, which is automatically released by the system; Store basic types, simple data segments, occupy a fixed amount of space

  • Heap: Dynamically allocated memory that varies in size and is not automatically freed. Holds reference types, objects that may consist of multiple values, in heap memory

Click here for details

Garbage collection mechanism

MDN says that since 2012, all modern browsers have used the mark-sweep garbage collection algorithm. All improvements to THE JS garbage collection algorithm are based on improvements to the mark-sweep algorithm

“What is garbage?” Generally speaking, objects that are not referenced are garbage and are only cleared. With one exception, if several objects refer to each other to form a ring, but the root cannot access them, they are also garbage (reference counting, cannot remove them).

“Algorithms for Garbage Collection:”

5-1 Reference counting method

Concept: Keep track of how many “programs” are referencing themselves, and when the referenced value is 0, start clearing it.

Advantage:

  • Can beimmediatelyRecycle garbage when the referenced value is0“, the object immediately identifies itself asFree spaceConnected to theFree listUp, in other words. As soon as it becomes garbageimmediatelyBe recycled.
  • Since it’s an instant collection, the program doesn’t pause to use GC alone for a long period of time, soThe largest suspendedtimeA short.
  • You don’t have to go through all the live and inactive objects in the heap

Disadvantage:

  • Counter needsA greatthelocationSince it is impossible to predict the upper limit of references, for example, it is possible to have 32 bits, that is, 2 ^ 32 objects referencing an object at the same time, and the counter needs 32 bits.
  • The biggest disadvantage isCircular references cannot be resolvedThis is the problem with IE9 previously mentioned

5-2 mark removal method

The GC garbage collection process is divided into two phases

Mark phase: Mark all active objects.

Cleanup phase: Destroy unmarked (and therefore inactive) objects.

Advantage:

  • The realization of simple, marked that is to play or not play two possibilities, so a binary bit can be expressed
  • Fixed the circular reference problem

disadvantages

  • Cause fragmentation (somewhat similar to disk fragmentation)
  • If a block size is never found, the free linked list (the list of addresses that hold all the free address Spaces in the heap) is traversed all the way to the end

5-3 Replication algorithm

  1. Divide a memory space into two parts, one isFromSpace, the other part isTospace
  2. willThe From spaceThe inside of theactivityobjectcopytoTo the space
  3. Release the wholeFromspace
  4. Then the identity of From space and To spaceswapThen a GC is completed.

Click here 1 for details

Click here 2 for details

6 Memory Leakage

“Concept:” The applied memory is not reclaimed in time, resulting in a waste of system memory, slowing down the running speed of the program, and even system crash

“Memory leak scenario:”

(1) Unexpected global variables

function leaks(){ leak = 'xxxxxx'; //leak becomes a global variable and is not recycled}Copy the code

(2) Timer for forgetting

The life cycle of setTimeout and setInterval is maintained by the browser’s dedicated thread. If the timer is used on a page and not manually released when the page is destroyed, the timer is still alive

(3) Improperly used closures

var leaks = (function(){ var leak = 'xxxxxx'; Return function(){console.log(leak); return function(){console.log(leak); }}) ()Copy the code

(4) Missing DOM elements

<div id="container"> </div> $('#container').bind('click', function(){ console.log('click'); }).remove(); // The dom is removed, but js still holds references to itCopy the code

Solution:

$('#container').bind('click', function(){ console.log('click'); }).off('click').remove(); // Remove the event from memoryCopy the code

(5) Network callback

“How to Monitor memory Leaks”

  • Use console
  • Click here for details

7 the scope

Extension:

JavaScript is a portal dynamic language. Unlike Java, JavaScript can define global and local variables at will. Each function is a scope.

JavaScript is static scoped, and when a variable is queried, its value is determined by the position at which the function is defined, regardless of the scope at which it is executed.

ES6 already has block-level scope, and variables defined with lets and const are not promoted.

Concept:

Scope: The effective scope of a variable or function

Scope chain: if we need to find a value of a variable, we will first look in the current scope. If we can’t find it, we will look up one level. If we find it, we will return to stop the search and return the value of the search

7-1 Related cases

(1) Variable promotion/variable is determined by the position at which the function is defined

var a = 1;
function fn() {
  console.log('1:' + a);
  var a = 2;
  bar()
  console.log('2:' + a)
}
function bar() {
  console.log('3:' + a)
}
fn()
Copy the code

1:undefined 3:12 2:2

What is the meaning of?

The first a prints 1:undefined instead of 1. Since we defined variable a in fn(), the variable defined with var will be promoted to the top of the current scope, but the assignment will remain in place, so undefined.

The second A prints a value of 3:1 instead of 2. The function bar is defined in the global scope, so the scope chain is bar -> global. There is no definition of A in bar, so we will look up the scope chain and find a in global. Note: Lookups are lookups in their defined execution context.

The third a prints the value 2:2. Fn -> global, console.log(‘2:’ + a) will find a in fn’s scope, and it has been assigned to 2, so the result is 2.

(2) Variable assignment

var a = 1;
function fn() {
  console.log('1:' + a);
  a = 2
}
a = 3;
function bar() {
  console.log('2:' + a);
}
fn();
bar();
Copy the code

Print them separately: 1:3 2:2

What is the meaning of?

The first printed value is 1:3. First, a = 2 in fn assigns a value to variable A, not to declare a variable. Next, the function fn, at which point a has been assigned a value of 3, is executed after a=3.

The second printed value is 2:2. Function bar can access the scope chain as bar->global. When the function bar is executed, fn() is executed before bar to change a to 2, so the a is 2.

(3) Global variable declaration in advance

if(! (a in window)){ var a = 10; } console.log(a);Copy the code

Print: undefined

What is the meaning of?

Is equivalent to:

var a; if(! (a in window)){ a = 10; } console.log(a);Copy the code

Variables defined with var are promoted to the top of the current scope (i.e. the current global scope), so a is declared ahead of time in the window, but the value remains in place, i.e. undefined. Console. log(a) == undefined

Variations on the previous example:

(function(){
 var  x = c =  b = {a:1}
})()
console.log(c,b) // {a: 1} {a: 1}
console.log(x.a); // error , x is not defined
Copy the code

Note: x is declared as a local variable, c and b are not declared and assigned directly, so they are global variables. The assignment process goes from right to left, that is, b={a:1},c=b,x=c

(4) Variable promotion/operator order

(function(){
  var a = b = 3;
})()
console.log(typeof a === "undefined"); // true
console.log(typeof b === "undefined"); // false
console.log(typeof b === "number" && b ===3); // true
Copy the code

// There are immediate execution and closure issues involved, as well as variable promotion, operator execution direction (= sign from right to left)

// That function can be split like this

(function() var a; /* local variable, external cannot access */ b = 3; /* a = b; /* a = b; }) ()Copy the code

(5) Variable promotion/operator order

var x = 1;
if (function f(){console.log(2)}) {
x += typeof f;  
}
console.log(x);  // 1undefined
Copy the code

// Since the function body is run as an expression in (), the fn function does not work and the function is not executed.

// Finally, the expression is converted to true,f is not declared (the above function does not work), and the value is undefined

“Knowledge:”

(1) In JavaScript, variables defined by lets and const have block-level scoping.

(2) Variables defined by var are promoted in their own scope, while variables defined by let and const are not.

(3) Every JavaScript program has a global scope, and a scope is created for every function created.

(4) When creating a function, these functions will be nested, and their scope will be nested, forming a scope chain. The child scope can access the parent scope, but the parent scope cannot access the child scope.

(5) When executing a function, if we need to find a variable value, we will search in the scope chain where the function is defined. Once we find the variable we need, we will stop searching up.

(6) The value of a variable is determined by the position at which the function is defined.

8 closure

“Concept:”

A function returns a child function that accesses the parent function’s variables.

Application Scenario:

  • Function image stabilization
  • Encapsulating private variables
  • Solve for loop variables influence each other

Target: You want to print 0-9 in order

for(var i = 0; i < 10; I++) {setTimeout (() = > console. The log (I), 0)} / / actual console output for ten times ten.Copy the code

Use closures

for(var i = 0; i < 10; {setTimeout i++) {(function (a) (() = > console, log (a), 0)}) (I)} / / console output 0-9Copy the code

How do closures come about

The current scope produces a reference to the parent scope

The whole execution process of JavaScript code is divided into two stages: code compilation stage and code execution stage. The compilation phase is done by the compiler, translating code into executable code, where scoping rules are determined. The execution phase is done by the engine and the main task is to execute executable code. The execution context is created in this phase.

9 this

9-1 The direction of this:

ES5:

This always refers to the object that last called it

ES6 arrow functions:

The arrow function’s this always points to this when the function is defined, not when it is executed.

9-2 How to change the direction of this:

  • Use the arrow function of ES6
  • Use _this = this inside the function
  • Use apply, call, and bind
  • New instantiates an object

Case 1:

var name = "windowsName"; var a = { name : "Cherry", func1: function () { console.log(this.name) }, func2: function () { setTimeout( function () { this.func1() },100); }}; a.func2() // this.func1 is not a functionCopy the code

Without the arrow function, an error is reported because the last object to call setTimeout is the window, but there is no func1 function in the window. Think of it as window.settimeout

Case 2:

var webName="long"; let func=()=>{ console.log(this.webName); } func(); //longCopy the code

The arrow function is declared in global scope, so it captures this in global scope, which points to the window object

Case 3:

var webName = "long"; function wrap(){ let func=() => { console.log(this.webName); } func(); } wrap(); //longCopy the code

// When wrap is executed, the arrow function func is defined in wrap, and func finds its closest layer of non-arrow function this

// This for wrap, and this in the wrap function’s scope refers to the window object.

9-3 Arrow functions:

It is well known that the arrow function in ES6 avoids the use of this in ES5. The arrow function’s this always points to this when the function is defined, not when it is executed.

Arrow functions need to keep this in mind: “Arrow functions have no this binding and must determine its value by looking up the scope chain. (Arrow functions don’t have this themselves, but can capture someone else’s this for their own use when they declare it.) If the arrow function is contained by a non-arrow function, then this is bound to this of the nearest non-arrow function; otherwise, this is undefined.

Features:

  • There is no this
  • Without the arguments
  • Cannot be called by the new keyword
  • There is no new target
  • There is no prototype
  • There is no super

Click here for details

Prototype and prototype chain

Background: 10-1

A function can be thought of as a class, and a stereotype is an attribute shared by all classes. The purpose of a stereotype is to add a uniform method to each object of the class

10-2 Basic Concepts

“Prototype:” Every function has this property, but normal objects don’t have this property. It is the prototype object for the constructor;

“” Proto” : “Every object has this property, emphasis here, is an object, and also, since functions are objects, functions have this property too. It points to the constructor’s prototype object;

“Constructor:” This is a property on the prototype object that points to the constructor.

var webName = "long"; Function Pig(name, age) {this.name = name; this.age = age; } // create a Pig instance. Var Peppa = new Pig('Peppa', 5); Peppa. __proto__ = = = Pig. The prototype. //true Pig.__proto__ === Function.prototype //true Pig.prototype.constructor === Pig //trueCopy the code

Bizarre tricks: Han Xin on drink (function display prototype = object of the Hermit prototype) click here for details

10-3 What is archetypal inheritance

An object can use properties or methods of another object. This is called inheritance.

Specifically, by setting the prototype of this object to another object, according to the rules of the prototype chain, if an object property is searched and it does not exist, another object will be searched, equivalent to an object can use the properties and methods of another object.

11 Shallow copy

11-1 shallow clone

function shallowClone(obj) {
  let cloneObj = {};
  
  for (let i in obj) {
    cloneObj[i] = obj[i];
  }
  
  return cloneObj;
}

Copy the code

11-2 deep cloning

Deep cloning:

  • Consider base types

  • Reference types

  • RegExp, Date, and functions are not JSON-safe

  • Constructor is lost, with all constructors pointing to Object

  • Breaking circular references

function deepCopy(obj) {
  if (typeof obj === 'object') {
    var result = obj.constructor === Array ? [] : {};
    
    for (var i in obj) {
      result[i] = typeof obj[i] === 'object' ? deepCopy(obj[i]) : obj[i];
    }
  } else {
    var result = obj;
  }
  
  return result;
}
Copy the code

Click here for details

An array of 12

12-1 array decrement

1. es6的new Set

Let arr =,2,2,3 [1] let arrNew = new Set (arr) [...] the console. The log (arrNew) / / [1, 2, 3]Copy the code

2. Iterate through the old array to add a unique element to the new array

function unique(arr) { var newArr = [] for (var i = 0; i < arr.length; I++) {f (newArr indexOf (arr) [I] = = = 1) {/ / way 1 newArr. Push (arr) [I]} / / if (! Newarr. push(arr[I]) //}} return newArr} console.log(unique(arr))//[1,2,3]Copy the code

3. Use the Map data structure for deduplication

function unique(){ let map =new Map() let arr=new Array() for(let i=0; i<arr.length; I ++){if(map.has(arr[I])){ Set (arr[I],true)}else{map.set(arr[I],false)// If there is no key array.push(arr[I])}} return array} The console. The log (unique) (,2,2,3 [1])Copy the code

Resolution:

Store each element as a key value in the Map. Since the Map does not have the same key, the final result is de-duplicated.

12-2 Array expansion

1. The flat method

Let arr = [1, 2, 3, 4], [5] [6, 7]] let arr1 = arr. Flat (Infinity) / /,2,3,4,5,6,7 [1]Copy the code

2.join,split

Let arr = [1, 2, 3, 4], [5] [6, 7]] let arr1 = arr. The join (). The split () ", "/ / /" 1 ", "2", "3", "4", ""]Copy the code

3.toString,split

Let arr = [1, 2, 3, 4], [5] [6, 7]] let arr1 = arr. ToString (). The split () ", "/ / /" 1 ", "2", "3", "4", ""]Copy the code

12-3 Array merge

1. Es6 expands the merge

Let arr1 = [1, 2] let arr2 = [3, 4] let arr = [arr1,... arr2] / / [1, 2, 3, 4]Copy the code

2. The concat

  let arr = arr1.concat(arr2)
Copy the code

12-4 Judge the array

instanceof

   console.log(arr instanceof Array)
Copy the code

constructor

   console.log(arr.constructor === Array)
Copy the code

Array.isArray

   console.log(Array.isArray(arr))
Copy the code

toString

   console.log(Object.prototype.toString.call(arr) === "[object Array]")
Copy the code

Determine if there is an array push method

console.log(!! arr.push && !! arr.concat)Copy the code

13 object

13-1 How can I determine whether an object is empty

1. Convert the JSON object to a JSON string and check whether the string is “{}”.

var data = {};

var b = (JSON.stringify(data) == "{}"); //true

Copy the code

2. For in

var obj = {}; var b = function() { for(var key in obj) { return false; } return true; } b(); //trueCopy the code

3. Jquery isEmptyObject method

This method is a jquery wrapper for in, and you need to rely on jquery

var data = {}; var b = $.isEmptyObject(data); alert(b); //trueCopy the code

4. Object. GetOwnPropertyNames () method

This method uses the getOwnPropertyNames method of an Object Object. It retrieves the property names of the Object, stores them in an array, and returns an array Object. We can determine whether the Object is empty by judging the length of the array

Note: This method is not compatible with IE8 and is not tested for other browsers

var data = {}; var arr = Object.getOwnPropertyNames(data); alert(arr.length == 0); //trueCopy the code

5. Use the ES6 object.keys () method

Similar to the 4 method, is a new method in ES6. The return value is also an array of property names in the object

var data = {}; var arr = Object.keys(data); alert(arr.length == 0); //trueCopy the code

14 map

Difference between Map and weakMap

A map is essentially a collection of key-value pairs, but the keys in a normal Object key-value pair can only be strings. The Map data structure provided by ES6 is similar to an object, but its key can be of any type without limitation. It is a more complete Hash structure.

If the Map’s key is of a primitive data type, the two keys are considered the same as long as they are strictly the same.

In fact, a Map is an array, and each of its data is an array, as follows:

Const map = [["name"," age"], ["age",18],]Copy the code

Map data structures have the following operations:

  • Size: map.size Returns the map structureTotal number of members.
  • Set (key,value) : sets the corresponding key nameKey valueIf the key already has a value, the key value will be updated, otherwise the key will be generated. (Can be chained because it returns the current Map object)
  • Get (key) : this method reads the corresponding keyThe key valueIf key cannot be found, return undefined.
  • Has (key) : This method returns oneBoolean value, indicating whether a key is in the current Map object.
  • Delete (key) : This method deletes a key and returns true, or false if the deletion fails.
  • Clear () : map.clear() clears all members with no return value.

The Map structure natively provides three traverser generating functions and one traversal method

  • Keys () : returnsKey nameThe traverser of.
  • Values () : returnsThe key valueThe traverser of.
  • Entries () : Returns all membersThe traversal.
  • ForEach () : traverses the MapAll the members.
const map = new Map([
     ["foo",1],
     ["bar",2],
])
for(let key of map.keys()){
    console.log(key);  // foo bar
}
for(let value of map.values()){
     console.log(value); // 1 2
}
for(let items of map.entries()){
    console.log(items);  // ["foo",1]  ["bar",2]
}
map.forEach( (value,key,map) => {
     console.log(key,value); // foo 1    bar 2
})
Copy the code

15 v8 engine

15-1 V8 garbage collection

“Background:”

V8’s garbage collection strategy is based on generational collection, which in turn is based on the generation hypothesis.

This hypothesis has two characteristics:

  • Most of thenewObjects tend toEarly death;
  • The undeadObject, willliveHave tolonger.

Based on this theory, modern garbage collection algorithms divide memory into generations according to the lifetime of objects, and adopt different efficient algorithms for garbage collection of different generations of memory.

“V8 Memory Generation”

In V8, memory is divided into New space and old space.

Their characteristics are as follows:

Cenozoic: Objects live for a short time. Newborn objects or objects that have been garbage collected only once.

Old generation: The object lives for a long time. Objects that have undergone one or more garbage collections.

“V8 heap space”

The V8 stack is equal to the new generation plus the old generation. You can use the –max-old-space-size command to set the maximum size of the old generation space and –max-new-space-size command to set the maximum size of the new generation space. The space size of old generation and new generation is set during program initialization and cannot be changed dynamically once it takes effect.

  • Node –max-old-space-size=1700 test.js // Unit: MB
  • Node –max-new-space-size=1024 test.js // Unit: KB

By default, the old generation size is 1400 MB for 64-bit systems and 700 MB for 32-bit systems.

For Cenozoic generations, it consists of two reserved_semispace_sizes. The size of each reserved_semispace_size varies on machines with different bits. By default, it is 16MB on 64-bit and 8MB on 32-bit systems. The new generation, old generation and reserved_semispace_size space sizes are summarized in the following table.

Type \ System bits A 64 – bit 32 –
The old generation 1400MB 700MB
reserved_semispace_size 16MB 8MB
The new generation 32MB 16MB

Click here for details

16 event loop

16-1 What is an event loop

Click here 1 for details

Click here 2 for details

Advantages and disadvantages of strict mode

17-1 concept

A method introduced in ECMAScript 5 to introduce better error checking into code is now implemented by most browsers. This mode makes Javascript run under stricter conditions

17-2 advantages

  • Global variables can no longer be accidentally created.
  • Causes an assignment operator that causes silently fail (i.e., no error and no effect) to throw an exception.
  • An exception is thrown when an attempt is made to remove a non-deletable property (previously this had no effect).
  • The parameter name of the function is required to be unique.
  • Globally, the value of this is undefined.
  • Some common coding errors are caught and exceptions are thrown.
  • Disable confusing or poor features.

17-3 faults

  • Missing features that many developers have become accustomed to.
  • Unable to access function.caller and function.arguments.
  • Scripts written in different strict modes can cause problems when combined.

18 ES6

18-1 background

EC version Release time The new features
2009(ES5) In November 2009 Extended Object, Array, Function and other new features
2015(ES6) In June 2015 Classes, modularity, arrow functions, default values for function parameters, etc
2016(ES7) In March 2016 Includes, the index operator
2017(ES8) In June 2017 Sync /await, object.values (), object.entries (), String padding, etc

18-2 Common Features

  • class
  • modular
  • Arrow function
  • Function parameter default value
  • Template string
  • Deconstruction assignment
  • Extension operator
  • Short for object property
  • Promise
  • Let the Const

“(1) Class”

In traditional javascript, there are only objects, not classes.

It is an object-oriented language based on prototypes. Prototype objects typically share their properties with new objects. This writing method relative to other traditional object-oriented language, there is a unique feeling foot! It’s very confusing! If you want to generate an instance of an object, you define a constructor and do so using the new operator.

Here is an example of the constructor’s evolution to class:

Constructor —

function Person(name,age) { this.name = name; this.age=age; } Person. Prototype. Say = function(){return "this.name "+" this.name "+ "this.age "; } var obj=new Person("laotie",88); // The new operator console.log(obj.say()) must be used to create objects using constructors; My name is Laotie and I am 88 years oldCopy the code

ES6 introduces the concept of Class, which can be defined by the Class keyword.

The emergence of this keyword makes it clearer in object writing and more like an object-oriented language.

If you changed the previous code to ES6, it would look like this:

class–

Constructor (name,age){// Constructor is a constructor that takes the parameter this.name = name; //this represents the instance object this.age=age; } say(){return "my name is "+this. name+" this "+this.age+" age "; } } var obj=new Person("laotie",88); console.log(obj.say()); Console. log(typeof Person); // Laotie is 88 years old. / / function - class is essentially a function of the console, log (Person = = = Person. The prototype. The constructor); //true // The class itself points to the constructor. So you can assume that classes in ES6 are just another way of writing constructors!Copy the code

Note:

  1. When declaring a method in a class, never add the function keyword to the method

  2. Do not separate methods with commas, otherwise an error will be reported

  3. Class does not have variable promotion, so you need to define it before you use it. Unlike ES6, which does not elevate class declarations to code headers,ES5 has variable promotions that can be used first and defined later.

//ES5 can be used before definition, there is variable promotion new A(); Function A(){//ES6 (){//ES6 (); //B is not defined class B{ }Copy the code

“(2) Module”

background

There was no concept of modularity in javascript before. If you want to modularize operations, you need to introduce third-party libraries. With the development of technology, the front and back ends are separated, and the front-end services become more and more complicated. It wasn’t until ES6 introduced modularity that javascript supported modules for the first time. The modularity of ES6 is divided into export and import modules.

The use of the export

In ES6, each module is a file, and variables, functions, and objects defined in the file are not accessible externally. If you want the contents of a module to be read externally, you must use export to expose it.

Let’s start with an example of modularizing a variable.

Export let myName="laowang"; export let myName="laowang";Copy the code
// We can then create an index.js file and import the variable as import: import {myName} from "./test.js"; console.log(myName); //laowangCopy the code

If you want to output multiple variables, you can package these variables as objects for modular output:

let myName="laowang"; let myAge=90; Let myfn=function(){return "myName+ myName+"! } export {myName, myAge, Myfn} * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * the received code is adjusted for * * * * * * * * * * * * * * * * * * * * * import {myfn myAge, myName} from ". / test. Js "; console.log(myfn()); // I am Laowang! Console.log (myAge); //90 console.log(myName); //laowangCopy the code

If you don’t want to expose the names of variables in the module, you can use as to do this:

let myName="laowang"; let myAge=90; Let myfn=function(){return "myName+ myName+"! } export {myName as name, myAge as age, Myfn as fn} / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * the received code is adjusted for * * * * * * * * * * * * * * * * * * * * * * / import {fn, age, name} from ". / test. Js "; console.log(fn()); // I am Laowang! I'm 90 years old console.log(age); //90 console.log(name); //laowangCopy the code

You can also import the entire module directly and change the receive code above to:

import * as info from "./test.js"; // Use * to batch receive, as to specify the name of the receive console.log(info.fn()); // I am Laowang! Console.log (info.age); //90 console.log(info.name); //laowangCopy the code

A module can have only one default export. For the default export, the import name can be different from the export name.

/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * export * * * * * * * * * * * * * * * * * * * * * * / export default function () {return} "default derived a method" / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * introduction of * * * * * * * * * * * * * * * * * * * * * * / import myFn from ". / test. Js "; // Note that {} is not required for export by default. console.log(myFn()); // Export a method by defaultCopy the code

You can put all the variables that need to be exported into one object and export them using default Export

/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * export * * * * * * * * * * * * * * * * * * * * * * / export default {myFn () {return "a method is derived by default"}, MyName: "laowang} /" * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * introduction of * * * * * * * * * * * * * * * * * * * * * * / import myObj from ". / test. Js "; console.log(myObj.myFn(),myObj.myName); // Export a method laowang by defaultCopy the code

Mixed exports are also supported

/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * derived * * * * * * * * * * * * * * * * * / export default function () {return} "a method is derived by default" export var myName="laowang"; / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * introduction of * * * * * * * * * * * * * * * * * * * * * * / import myFn, {myName} from ". / test. Js "; console.log(myFn(),myName); // Export a method laowang by defaultCopy the code

To solve this problem, ES6 provides a rename method. You can do this when importing names:

/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * test1. Js * * * * * * * * * * * * * * * * * * * * * * / export let myName = "I am from test1. Js"; / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * test2. Js * * * * * * * * * * * * * * * * * * * * * * / export let myName = "I am from test2. Js"; /******************************index.js**********************/ import {myName as name1} from "./test1.js"; import {myName as name2} from "./test2.js"; console.log(name1); // I'm from test1.js console.log(name2); // I'm from test1.jsCopy the code

(3) Arrow function

See the 1-5-3 arrow functions section:

The arrow function’s this always points to this when the function is defined, not when it is executed. Arrow functions need to remember this: “There is no this binding in arrow functions, and its value must be determined by searching the scope chain. If the arrow function is contained by a non-arrow function, this is bound to the nearest non-arrow function’s this; otherwise, this is undefined.”

“(4) Default Values of Function parameters”

ES6 supports setting default values for functions when they are defined:

function foo(height = 50, color = 'red')
{
    // ...
}
Copy the code

Do not use default values:

function foo(height, color) { var height = height || 50; var color = color || 'red'; / /... }Copy the code

This is generally fine, but when the argument has a Boolean value of false, it becomes a problem. For example, we call foo: foo(0, “”) because 0 has a Boolean value of false, height will be 50. In the same way color is’ red ‘. So, function parameter defaults can not only make the code cleaner but also avoid some problems.

(5) Template String

ES6 supports template strings in defining functions, making string concatenation more concise and intuitive.

Without using template strings:

var name = 'Your name is ' + first + ' ' + last + '.'
Copy the code

Using template strings:

var name = `Your name is ${first} ${last}.`
Copy the code

In ES6, concatenation of strings can be done with ${}, simply by enclosing variables in braces.

“(6) Deconstructing Assignment”

Destruct assignment syntax is a JavaScript expression that allows you to quickly extract values from arrays or objects and assign them to defined variables.

Gets the value in the array

// Get values from the array and assign values to variables in the order of the objects in the array. var foo = ["one", "two", "three", "four"]; var [one, two, three] = foo; console.log(one); // "one" console.log(two); // "two" console.log(three); // "three"Copy the code
Var [first,, last] = foo; var [first,, last] = foo; var [first,, last] = foo; console.log(first); // "one" console.log(last); // "four"Copy the code
// You can also write var a, b; [a, b] = [1, 2]; console.log(a); // 1 console.log(b); / / 2Copy the code
// If no value is retrieved from the array, you can set a default value for the variable. var a, b; [a=5, b=7] = [1]; console.log(a); // 1 console.log(b); / / 7Copy the code
// We can easily swap the values of two variables by destructing assignments. var a = 1; var b = 3; [a, b] = [b, a]; console.log(a); // 3 console.log(b); / / 1Copy the code

Gets the value in the object

const student = {
  name:'Ming',
  age:'18',
  city:'Shanghai'  
};
const {name,age,city} = student;
console.log(name); // "Ming"
console.log(age); // "18"
console.log(city); // "Shanghai"
Copy the code

Deep retrieves the value of an object

Const school = {classes: {stu: {name: 'Bob', age: 24,}}} const {classes: {stu: { name } }} = school console.log(name) // 'Bob'Copy the code

“(7) Extension operator”

The extension operator in ECMAScript 2018 adds support for objects that can be used to unpack images and arrays

var obj1 = { foo: 'bar', x: 42 }; var obj2 = { foo: 'baz', y: 13 }; var clonedObj = { ... obj1 }; // Clone object: {foo: "bar", x: 42} var mergedObj = {... obj1, ... obj2 }; // Merged object: {foo: "baz", x: 42, y: 13} The same attributes are overwrittenCopy the code
Var arr1=['a','b','c']; var arr2=[...arr1,'d','e']; //['a','b','c','d','e']Copy the code
Var arr1=['a','b','c']; var arr1=['a','b','c']; var arr2=['d','e']; arr1.push(... arr2); //['a','b','c','d','e']Copy the code
Let [arg1,arg2...arg3] = [1, 2, 3, 4]; arg1 //1 arg2 //2 arg3 //['3','4']Copy the code
Let [arg1,...arg2,arg3] = [1, 2, 3, 4]; let [arg2,arg3] = [1, 2, 3, 4]; / / an errorCopy the code

“(8) Object Property Abbreviation”

ES6 allows you to set an object’s properties without specifying the property name.

Do not use the ES6

const name='Ming',age='18',city='Shanghai'; const student = { name:name, age:age, city:city }; console.log(student); //{name: "Ming", age: "18", city: "Shanghai"} // The object must contain attributes and values, which are very redundant.Copy the code

Use the ES6

const name='Ming',age='18',city='Shanghai'; const student = { name, age, city }; console.log(student); //{name: "Ming", age: "18", city: "Shanghai"}Copy the code

What is a Promise

Promise is a solution to asynchronous programming that is more reasonable and powerful than traditional asynchronous solution callbacks and events. It is now incorporated into the specification by ES6.

Here are a few cases to deepen the understanding of promise:

(1) The Promise constructor is executed synchronously; then is asynchronous

const promise = new Promise((resolve, Reject) => {console.log(1) resolve() console.log(2)}) promise.then(() => {console.log(3)}) console.log(4) 1 2 3 4Copy the code

The Promise constructor is executed synchronously, and the functions in promise.then are executed asynchronously.

(2) Once the promise status changes, it cannot be changed again

const promise = new Promise((resolve, reject) => { resolve('success1') reject('error') resolve('success2') }) promise .then((res) => { console.log('then: ', res)}). Catch ((err) => {console.log('catch: ', err)}Copy the code

Resolve or reject are valid only on the first execution. Multiple calls to the constructor do nothing. Once the promise state changes, it cannot be changed again.

(3). Then or. Catch both return a new promise

Promise.resolve(1) .then((res) => { console.log(res) return 2 }) .catch((err) => { return 3 }) .then((res) => { Console. log(res)}) // Result: 1 2Copy the code

Parse: Promise can be called chained. When we think of chained calls we usually think of a return this implementation, but that’s not how promises are implemented. A promise returns a new promise each time it is called. Then or. Catch, thereby implementing the chained invocation.

(4) The Promise constructor is executed only once

const promise = new Promise((resolve, reject) => { setTimeout(() => { console.log('once') resolve('success') }, 1000) }) const start = Date.now() promise.then((res) => { console.log(res, Date.now() -start)}) promise.then((res) => {console.log(res, date.now () -start)}) once success 1005 success 1007Copy the code

Parsing: a promise’s.then or.catch can be called multiple times, but here the Promise constructor is executed only once. Or once the internal state of the promise changes (the first time.then is called) and there is a value, each subsequent call to.then or.catch will get that value directly.

(5). Then or. Catch both return a new promise

Promise.resolve() .then(() => { return new Error('error!!! ')}). Then ((res) = > {the console. The log (' then: 'res)}). The catch ((err) = > {the console. The log (' catch:' err)}) / / run results: then: Error: error!!! at Promise.resolve.then (...) at ...Copy the code

An error object in a. Then or. Catch does not throw an error, so it will not be caught by a subsequent. Catch.

  1. return Promise.reject(new Error(‘error!!! ‘))
  2. throw new Error(‘error!!! ‘)

Return new Error(‘ Error!!! ‘) because returning any non-Promise value is wrapped as a Promise object. ‘) equivalent to return promise.resolve (new Error(‘ Error!!! ‘)).

(6) the value returned by.then or.catch cannot be the promise itself

Const promise = promise.resolve ().then(() => {return promise}) promise.catch(console.error) // TypeError: Chaining cycle detected for promise #<Promise> at <anonymous> at process._tickCallback (internal/process/next_tick.js:188:7) at Function.Module.runMain (module.js:667:11) at startup (bootstrap_node.js:187:16) at bootstrap_node.js:607:3Copy the code

The value returned by. Then or. Catch cannot be the promise itself, otherwise it will cause an infinite loop.

(7). Then function return value type and parameter passing

Resolve (2) // Resolve (2) returns a Promise<number> object. Then (x=>{console.log(x); Return "hello world"; // Return "hello world"; // Then returns Promise<string>. Then (x=>{console.log(x); }}}}}}}}}}}}}} Then (x=>{// then callback does not return a value, so this x is undefined console.log(x); Return promise.resolve ("hello world"); return promise.resolve ("hello world"); return promise.resolve ("hello world"); // Return a Promise<string>. Then (x=>{// The then callback returns a Promise<string> but x is not a Promise<string> but a string console.log(x); // hello world return Promise.resolve(2); // Returns a Promise<number> objectCopy the code

(8).then or.catch parameters are expected to be functions, and value penetration occurs when passing non-functions.

Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log)  //1
Copy the code

Parsing:.then or.catch parameters are expected to be functions; passing non-functions will result in value penetration.

(9).catch is equivalent to short for.then (omits the second argument to.then)

Promise.resolve() .then(function success (res) { throw new Error('error') }, function fail1 (e) { console.error('fail1: Error ('fail2: ', e)}). Catch (function fail2 (e) {console.error('fail2: ', e)}) at ...Copy the code

Parsing:.then can take two arguments, the first is the function that handled the success, and the second is the function that handled the error. .catch is also equivalent to a.then, with the second argument omitted, but there is a caveat to their use: the second error-handling function of a.then cannot catch the error thrown by the first successful function, while subsequent.catches can catch the previous error.

(10) The execution sequence of micro tasks and macro tasks

process.nextTick(() => { console.log('nextTick') }) Promise.resolve() .then(() => { console.log('then') }) SetImmediate (() => {console.log('setImmediate')}) console.log('end') //Copy the code

Then is a microtask, while setImmediate is a MacroTask that executes during the check phase of the event loop. Microtasks are executed between each phase of the event cycle (MacroTasks), with a MicroTask executed at the beginning of the event cycle.

“(10) let and const”

View the 1-1JS variable declarations

The 19th event flow

Event flow is the order in which web elements receive events. The event flow specified by “DOM2-level events” includes three stages: event capture stage, target stage and event bubbling stage.

  • Event capture, which occurs first, provides an opportunity to intercept events.
  • Then there is the actual target acceptance event.
  • The final phase is the time bubble phase, where events can be responded to.

Although the capture phase is not allowed in the specification to respond to events, it is actually executed anyway, so there are two chances to get the target object.

<! DOCTYPE HTML > < HTML lang="en"> <head> <meta charset="UTF-8"> <title> Event bubble </title> </head> <body> <div> <p Id ="parEle"> I am the parent <span id="sonEle"> I am the child </span> </p> </div> </body> </ HTML > <script type="text/javascript"> var sonEle = document.getElementById('sonEle'); var parEle = document.getElementById('parEle'); Parele.addeventlistener ('click', function () {alert(' parent bubble '); }, false); Parele.addeventlistener ('click', function () {alert(' parent capture '); }, true); Sonele.addeventlistener ('click', function () {alert(' child bubble '); }, false); Sonele.addeventlistener ('click', function () {alert(' subcatch '); }, true); </script>Copy the code

When container elements and nested elements invoke event handlers, both in the capture phase and in the bubble phase: Events execute event handlers in the sequence of DOM event streams:

Parent capture = Child capture = Child bubble = Parent bubble

  • Click “I am the parent element” and pop up (‘ Parent capture ‘= ‘parent bubble’)
  • Click “I am the parent element” and pop up (‘ Parent capture ‘= ‘child capture ‘=’ child bubble ‘= ‘Parent bubble’)

Bizarre technique: Three stages can be remembered as capturing female cat (capture, target, bubble)

20 new

Construct call:

  • Create an entirely new object
  • This object will be linked by [[Prototype]], linking the [[Prototype]] of the new object to the object that Prototype points to
  • This new object is bound to the function call’s this
  • If the function returns no other object, the function call in the new expression automatically returns the new object

21 written promise

Js script loading problem, async, defer

22-1 Normal mode

In this case, JS blocks the browser and the browser must wait for index.js to load and execute before it can do anything else.

<script src="index.js"></script>
Copy the code

22-2 Async mode

In async mode, JS does not block the browser from doing anything else. It loads asynchronously, and when it finishes loading, the JS script executes immediately.

<script async src="index.js"></script>
Copy the code

22-3 Defer (Defer) mode

In the defer mode, JS loads are asynchronous and execution is deferred. When the entire document has been parsed and the DOMContentLoaded event is about to be triggered, the JS files that have been tagged defer will start executing in sequence.

<script defer src="index.js"></script>
Copy the code

From an application point of view, async is usually used when the dependencies between our script and DOM elements and other scripts are not strong; When the script depends on DOM elements and the execution results of other scripts, we choose defer.

23 Performance Optimization

What is performance optimization, why do we optimize, and what we optimize for? Only by thinking about these questions can we find corresponding solutions.

What is performance tuning?

It can run faster and take less time to complete specific functions without affecting the correctness of system operation. In short, it makes our programs run faster.

Why performance tuning?

Performance is very important to retain users, generally people can tolerate a web page load time is less than 5 seconds, performance optimization is also the guarantee of efficient operation of the program.

What are we optimizing for?

The optimization object is the program and the vehicle (such as a browser) on which the program is running.

We already know what the object of performance optimization is, so the next can be divided into several categories according to the optimization object summary, for the front end, the program and the carrier is nothing more than the following 5 points:

  1. html
  2. css
  3. js
  4. Application related tools
  5. The browser

So that we can expand it so that it’s clear and we don’t miss anything.

When summarizing each category, start with the overall document format, move to external resources, and then to the code level

1. html

HTML should think of semantic tags first. Proper semantic tags can make our document structure clearer. The js file is written after the body tag to prevent blocking pages from loading.

  • Semantic label, clear structure
  • Js files are placed correctly to prevent blocking

2.css

  • The CSS file should be placed at the top of the body tag to prevent the page from shaking for a second rendering.
  • Sprite can be used when there are many small images to reduce page requests.
  • Small ICONS can be base64 format to reduce page requests.
  • Common CSS extraction, code reuse
  • Multiple CSS are merged to reduce HTTP requests
  • Selector optimization nesting, as far as possible to avoid too deep hierarchy, shorten the search process
  • Take advantage of CSS inheritance properties to reduce the amount of code
  • To reduce page redrawing, you can first manipulate all styles with a variable and then, as a last step, associate that variable with the DOM

3.js

  • Remove common JS and reuse code
  • Remove common components and reuse code
  • Timer remember to clear, less memory consumption
  • V-if and V-show are used correctly with less page DOM construction
  • Throttling and shaking proof to prevent accidental triggering
  • Long list scrolling to visual area dynamic loading (big data rendering)
  • Computed and Watch differentiate usage scenarios and reduce performance costs
  • V-for traversal must add a key to the item and avoid using v-if at the same time

4.webpack

  • Remove code comments and compress the program
  • ——- install image-webpack-loader –save-dev, and configure it in webpack.config.js
  • Reduce redundant code from ES6 to ES5
  • Extract common code
  • Template precompilation
  • Optimize SourceMap
  • Build results output analysis
  • Use webpack-bundle-Analyzer to view all packages and volume sizes for your project

5. The browser

  • Loading on the first screen optimized the experience
  • Use caching to reduce repeated requests
  • Enable gzip compression to reduce requests
  • With CND, shorten the request chain
  • Use image lazy loading, component lazy loading, and route lazy loading to reduce requests
  • The introduction of third-party plug-ins on demand
  • Server render SSR or prerender
  • Use Chrome Performance to find Performance bottlenecks for targeted optimizations