1. JS Event Bubble and Event Proxy (delegate)

1. Event bubble

It is passed from the current event target, one level above the other, to the document.

<div id="childId1"> Delete the message </div></ div></body><script> Let parent = document.getElementById('parentId'); let childId1 = document.getElementById('childId1'); Parent-addeventlistener ('click', function () {alert(' view message information '); }, false); ChildId1. AddEventListener (' click ', function () {alert (' delete message information); }, false); // For example, the delete button in the start message list performs the delete operation first, and then bubbles up to execute 'View message information'. // Print: delete message information to view message information </script>Copy the code

Native JS cancels event bubbling

try{ e.stopPropagation(); / / the Internet explorer browser} the catch (e) {window. Event. CancelBubble = true; // Internet Explorer}Copy the code

Vue.js cancels event bubble

<div @click.stop="doSomething($event)">Copy the code

2. Event Agent (commission)

A. Why use event delegate:

For example, there are 100 Li under ul, use for loop to traverse all li, and then add events to them, which requires constant interaction with DOM nodes. The more times the DOM is accessed, the more times the browser will redraw and rearrange, which will prolong the interaction ready time of the whole page. This is why one of the main ideas of performance optimization is to reduce DOM manipulation;

If you want to use event delegate, you will put all the operations in THE JS program, and the operation with the DOM only needs to interact once, which can greatly reduce the interaction with the DOM, improve performance;

B. Principle of event delegation

Event delegate: Takes advantage of the event bubble feature to register processing events that should be registered on the child element on the parent element, so that when you click on the child element and find that there is no corresponding event on the child element, you will find the corresponding event on the parent element. The advantages of this are:

1. Reduce DOM operations and improve performance.

2, you can add child elements at any time, the added child elements will automatically have the corresponding processing events.

<div id="box"> <input type="button" id="add" value=" add" /> <input type="button" id="remove" value=" delete "/> <input type="button" id="remove" value=" delete" /> <input type="button" id="remove" value=" delete "/> <input type="button" id="remove" value=" delete" / <input type="button" id="select" value=" select" /> </div> Window.onload = function () {var Add = document.getelementById (" Add "); var Remove = document.getElementById("remove"); var Move = document.getElementById("move"); var Select = document.getElementById("select"); Add. Onclick = function () {alert(' Add '); }; Remove.onclick = function () {alert(' alert '); }; Function () {alert(' alert '); }; Select.onclick = function () {alert(' Select '); Window.onload = function(){var oBox = document.getelementById ("box"); var oBox = document.getelementById ("box"); oBox.onclick = function (ev) { var ev = ev || window.event; var target = ev.target || ev.srcElement; If (target. The nodeName. ToLocaleLowerCase () = = 'input') {switch (target. Id) {case 'add' : alert (' add '); break; Case 'remove' : alert(' remove'); break; Case 'move' : alert(' move'); break; Case 'select' : alert(' select'); break; }}}} The event delegate can be used to accomplish all the effects in a single DOM operation, which is certainly better than aboveCopy the code

3. Event capture

It’s going to fire from document, and it’s going to fire from document to document, all the way down to the actual event target.

<div> <button> <p> Click to capture </p> </button></div> <script> var oP = document.querySelector; var oB = document.querySelector('button'); var oD = document.querySelector('div'); var oBody = document.querySelector('body'); Op.addeventlistener ('click', function () {console.log('p tag was clicked ')}, true); Ob.addeventlistener ('click', function () {console.log("button was clicked ")}, true); Od. addEventListener('click', function () {console.log('div was clicked ')}, true); Obody.addeventlistener ('click', function () {console.log('body was clicked ')}, true); </script> Click <p> click capture </p>, the order of print is: body=>div=>button=>p</body>Copy the code

Process: capture, then process, then bubble out.

2. The prototype chain

1. The origin and nature of prototype objects

To solve the problem of not being able to share common properties, we need to design an object specifically to store the properties shared by the object, so we call it a “prototype object.”

How it works: The constructor has a property called prototype that points to the prototype object. We put all shared properties and methods in the prototype object that the constructor’s prototype property points to. We don’t need to put shared properties and methods in the constructor. All instance objects generated by the implementation constructor can share properties.

Constructor: private property Prototype object: common propertyCopy the code

2. The relationship between them

The constructor property is referred to as the constructor property. Each instance object generated by the constructor has a proto property that points to the prototype object.Copy the code

So who does the _proto_ property of the prototype object point to? -> null

3. What is the prototype chain?

As the name implies, it must be a chain, and since each object has a _proto_ attribute pointing to the stereotype object, the stereotype object also has _proto_ pointing to the stereotype object, until it points to the null in the figure above, which reaches the top of the stereotype chain.

4. Prototype chains and inheritance usage scenarios

The prototype chain is mainly used for inheritance and code reuse. Because JS is not really an object-oriented language, inheritance is prototype-based rather than class-based,

A. Determine whether the stereotype of the function is in the stereotype chain of the object

Object instanceof function (not recommended)

B. Create a new object whose implicit stereotype points to the specified object

Object. The create (Object)

var obj = Object.create(Object.prototype);

obj.__proto__ === Object.prototype

[C]. Implementation of new

D. Class A extends B

Because ES6 - there is no concept of classes and inheritance. The essence of js implementation inheritance is to abstract the object constructor in JS into a class in my mind, and then use the protpType attribute of the constructor to encapsulate a class (another constructor), so that it perfectly inherits all the attributes and methods of the previous constructor. Because constructors can new a concrete object instance, this modernized object orientation and inheritance in JS.

3. Closures and garbage collection mechanisms

The concept of closures

The function f1 () {var n = 999; The function f2 () {alert (n); } return f2; } var result = f1 (); result(); / / 999Copy the code

In the above code, function f2 is included inside function f1, and all local variables inside f1 are visible to F2. But the reverse is not true. Local variables inside F2 are invisible to F1. This is the Javascript language’s unique “chain scope” structure, where a child object finds all the variables of its parent object one level up. So, all variables of the parent object are visible to the child object, and not the other way around.

Since f2 can read local variables in F1, we can read its internal variables outside f1 simply by returning f2.

Functions: one is to read the variables inside the function mentioned above, and the other is to keep the values of these variables in memory, mainly used to encapsulate private variables, providing some exposed interface

The garbage collection

** Garbage collection mechanism: There is a background process in the JavaScript engine called the garbage collector, which monitors all objects and deletes those that are not accessible **

Javascript automatically allocates memory when creating variables (objects, strings, etc.) and “automatically” frees them when they are not used. The process of freeing is called garbage collection. This “automation” is a source of confusion and gives JavaScript (and other high-level languages) developers the false sense that they can ignore memory management,

How it works: since f2 refers to its global variable n, f2 will always be in memory, and since n is a local variable of F1, f2 depends on f1, so f1 will always be in memory, unlike normal functions, where the variable is garbage collected after being called.

So, the function in setTimeout refers to the variable I in the outer for loop, causing I to remain in memory and not be collected, so by the time the JS queue executes the function, I is already 10, so 10 tens are printed.

Five, the use of closures

1) Because closure will make the variables in the function are saved in memory, which consumes a lot of memory, so we cannot abuse closure, otherwise it will cause performance problems of web pages, which may lead to memory leak in IE. The solution is to remove all unused local variables before exiting the function.

for (var i=1; i<=5; i++) { setTimeout( function timer() { console.log( i ); }, i*1000 ); } for (var I =1; i<=5; i++) { (function(j) { setTimeout( function timer() { console.log( j ); }, j*1000 ); })(i); } print: output 1 through 5 cause: the actual parameter is strongly dependent on the I inside the timer. With the closure, the variable I is stored in memory. When the output j is referred to, the value of the variable I is referred to by the external function. The value of I is based on the loop, and the output of the inside function is determined when the setTimeout is executed. For (let I =1; i<=5; i++) { setTimeout( function timer() { console.log( i ); }, i*1000 ); } print: output 1 through 5 because the let at the head of the for loop not only binds I to the for loop, it actually rebinds it to each iteration of the body of the loop, ensuring that the value at the end of the last iteration is reassigned. Function () in setTimeout belongs to a new domain. Variables defined by var cannot be passed into the execution domain of the function. This is done by taking advantage of the fact that the scope of the parameters of this anonymous function is different from that of the for parameter. This anonymous function is scoped like a class property and can be used by inner methods.Copy the code

4. Js event execution mechanism

The event loop is as follows:

  1. JS engine (the only main thread) in order to parse the code, encounter function declaration, directly skip, encounter function call, push;
  2. If it is a synchronous function call, the result is directly executed, and the synchronous function is popped on the stack and continues to the next function call.
  3. If it is an asynchronous function call, distributed to the Web API (multiple helper threads), the asynchronous function will pop off the stack and continue to the next function call;
  4. In Web API, after the asynchronous function completes processing in the corresponding helper thread, that is, the asynchronous function reaches the triggering condition (such as after the setTimeout set for 10s). If the asynchronous function is a macro task, it enters the macro task message queue; if it is a micro task, it enters the micro task message queue.
  5. Event Loop keeps checking the call stack and callback queue of the main thread. When the call stack is empty, it pushes the first task in the microtask message queue into the stack for execution. After the execution is complete, it takes the second microtask until the microtask message queue is empty. Then it takes the first macro task from the macro task message queue and pushes it onto the stack for execution. After the execution of the macro task is completed, before the execution of the next macro task, it takes out all the micro tasks in the micro task message queue and pushes them onto the stack for execution.
  6. The process repeats itself, and each time the microtask queue clears, the event cycle ends.

Granulation of js functions