1, Prototype and original chain
prototype
1. prototype attribute of function
Each function has a prototype attribute. By default, it points to an empty Object (that is, a prototype Object)
There is a property constructor in the prototype object, which points to the function object
2. Add attributes (usually methods) to prototype objects
Function: all instance objects of the function automatically own the properties (Methods) in the prototype
// Each function has a prototype attribute. By default, it points to an empty Object (that is, a prototype Object) console.log(Date.prototype, typeof Date.prototype); function fun(){ } console.log(fun.prototype);// By default, it points to an object empty object (there is no attribute defined by us) // There is a property constructor in the prototype object, which points to the function object console.log(Date.prototype.constructor === Date); // true console.log(fun.prototype.constructor === fun); // true // Add attributes (usually methods) to prototype objects - > instance objects can be accessed fun.prototype.test = function() { console.log('test Prototype object addition'); } var f = new fun(); f.test(); // test prototype object addition
Explicit prototype and implicit prototype
Each function has a prototype, that is, an explicit prototype attribute, which points to an empty object by default
Each instance object has one_ proto_ , It can be called implicit prototype
The value of the implicit prototype of an object is the value of the explicit prototype of its corresponding constructor
function Fn(){ // Inner statement: this prototype = {} } // Each function has a prototype, that is, an explicit prototype attribute, which points to an empty object by default console.log(Fn.prototype); // Each instance object has one__ proto__. It can be called implicit prototype var fn = new Fn(); // Inner statement: this__ proto__ = Fn. prototype console.log(fn.__proto__); // The value of the implicit prototype of the object is the value of the display prototype of its corresponding constructor console.log(Fn.prototype === fn.__proto__);// true // Adding methods to prototype objects Fn.prototype.test = function(){ console.log('Adding methods to prototype objects') } fn.test()
Function prototype attribute: automatically added when defining a function. The default value is an empty Object object
Object__ proto__ Property: automatically added when creating an object. The default value is the prototype property value of the constructor
Programmers can directly manipulate explicit prototypes, but not implicit prototypes (before ES6)
Prototype chain
function Fn(){ this.test1 = function(){ console.log('test()'); } } Fn.prototype.test2 = function(){ console.log('test2()') } var fn = new Fn(); fn.test1(); fn.test2();
When accessing an object property,
First search in its own attributes, and return if found
If not, follow__ proto__ This line looks up and returns when it is found
If it is not found, return undefined
Prototype chain alias: implicit prototype chain
Purpose: find object attributes
Constructor / prototype / instance object relationship
1. The Object pointed to by the display prototype of the function: the default is an empty Object instance Object (but the Object is not satisfied)
2. All functions are instances of Function (including the Function itself)
3. Object is the end of the prototype chain
function Fn(){ this.test1 = function() { console.log('test1()'); } } var fn = new Fn(); console.log(Fn.prototype instanceof Object); // true console.log(Object.prototype instanceof Object); // false console.log(Function.prototype instanceof Object); // true // All functions are instances of Function (including the Function itself) console.log(Function.__proto__ === Function.prototype); // true // Object is the end of the prototype chain console.log(Object.prototype.__proto__); // null
Prototype chain properties
1. When reading the object attribute value: it will be automatically found in the prototype chain
2. When setting the attribute value of an object: the prototype chain will not be found. If there is no such attribute in the current object, add the attribute and set the value directly
3. Methods are generally defined in the prototype, and attributes are generally defined on the object itself through the constructor
instanceof
How does instanceof judge
Expression: A instanceof B
If the display prototype object of B function object is on the prototype chain of A object, return true; otherwise, return false
Function is an instance generated by new itself
2, Execution context and execution context stack
Variable promotion and function promotion
// Output undefined var a = 3; function fn() { console.log(a); var a = 4; } fn(); // Within fn function, var a = 4; Actually equal to the following code function fn() { var a; // var a here; Is variable promotion console.log(a); // Output defined here a = 4; } // fn2 the function can be called directly before it is declared through function. Function declaration promotion fn2(); function fn2() { console.log('fn2()'); } fn3(); // It cannot be called here, because the following belongs to variable promotion, not function promotion. Function promotion needs to be declared through function var fn3 = function() { console.log('fn3()'); }
1. Variable declaration promotion
- Variables defined (declared) by var can be accessed before defining statements
- Value: undefined
2. Function declaration promotion
- Functions declared through function can be called directly before
- Value: function definition (object)
Execution context
Code classification (location)
Global code
Function (local) code
Global execution context
Determine the window as the global execution context before executing the global code
Preprocess global data
The global variable defined by var = = = "undefined" is added as the attribute of window
The global function declared by function = = = "is assigned (fun) and added as the method of window
Start executing global code
Function execution context
Before calling the function and preparing to execute the function body, create the corresponding function execution context object (virtual, existing in the stack)
Preprocess local data
Formal parameter variable = = = "assignment (argument) = = =" added as the attribute of execution context
arguments = = "assignment (argument list), added as execution context attribute
var defined local variable = = = "undefined", added as the attribute of the execution context
The function declared by function = = = "is assigned (fun) and added as the method of execution context
this = = = "assignment (object calling the function)
Start executing function body code
// Function execution context function fn(a1) { console.log(a1); // 2 console.log(a2); // undefined a3(); // a3() console.log(this); // Window, this is window, because the following call method is fn(2, 3) console.log(arguments); // Pseudo array (2,3) var a2 = 3; function a3() { console.log('a3()'); } } fn(2, 3);
Execution Context Stack
Before global code execution, JS engine will create a stack to store and manage all execution context objects
After the global execution context (window) is determined, it is added to the stack (stack pressing)
After the function execution context is created, it is added to the stack (stack pressing)
After the current function is executed, the object at the top of the stack is removed (out of the stack)
When all the code is executed, only window is left in the stack
var a = 10; var bar = function(x) { var b = ; foo(x + b); } var foo = function(y) { var c = 5; console.log(a + c + y); // The following figure does not consider the context of changing the print function } bar(10)
Examples
1,
/** * 1,What is output in turn? * 2,How many execution contexts are generated in the whole process? */ console.log('global begin:' + i); var i = 1; foo(1); function foo(i) { if (i == 4) { return; } console.log('foo() begin:' + i); foo(i + 1); // Calling itself in function is called recursion. console.log('foo() end:' + i); } console.log('global end:' + i); /** 1: undefined foo() begin:1 foo() begin:2 foo() begin:3 foo() end:3 foo() end:2 foo() end:1 global end:1 Each time you call yourself, you do not execute foo() end. After return ing in i == 4, the function will execute the remaining code one by one and get out of the stack, so execute foo() end at this time */ /** 2: Do not consider console log() 4 + 1 Times (4 times foo, 1 time global) */
2,
/** * 1 */ function a() {} var a; console.log(typeof a); // Output: function. Because the variable is promoted first and then the function is promoted. The promoted function a() takes effect /** * 2 */ if (!(b in window)) { // b in window is true because var b is written, that is, variable promotion has been carried out var b = 1; } console.log(b); // undefined the following is the test code if (false) { var b = 1; } console.log(b in window); // true /** * 3 */ var c = 1; function c(c) { console.log(c); } c(2); // Error, c is not a function reason: first promote the variable, then the function, and finally execute the code. // Equivalent to the following code, declare c first, assign a value to c before executing c(2) to make it a variable, not a function var c;// Antecedent lifting function c(c) { // After function promotion, it is executed when the function is promoted (execution does not mean call) console.log(c); } c = 1; // Perform assignment after variable promotion and function promotion c(2);
3, Scope and scope chain
Scope
understand
Scope is a "territory", an area where code is short
It is static (relative to the context object) and is determined when writing code
classification
global scope
Function scope
No block scope (ES6 has)
effect
Isolate variables. Variables with the same name under different scopes will not conflict
if (true) { var a = 4; // a can also be accessed outside the braces, and the block scope without braces } // global scope var a = 10, b = 20; function fn(x) { // Function scope fn var a =100, // Variable isolation c = 300; console.log('fn()', a, b, c, x); function bar(x) { // Function scope bar var a = 1000, // Variable isolation d = 400; console.log('bar()', a, b, c, d, x); } bar(100); bar(200); } fn(10);
Scope and global context
difference
1,
Outside the global scope, each function will create its own scope, which has been determined when the function is defined. Not when a function is called
In the global execution context, after the global scope is determined, js code is created immediately before execution
When the function execution context environment is called, it is created before the function body code is executed
2,
The scope is static. As long as the function is defined, it will always exist and will not change
The execution context is dynamic. It is created when the function is called. When the function is called, the context will be released automatically
3,
The execution context (object) is subordinate to the scope in which it is located
Global context = = > global scope
Function context = = > corresponding function scope
Scope chain
understand
A chain formed by the scope of multiple parent-child relationships. Its direction is from bottom to top (from inside to outside)
Variables are found along the scope chain
Find rules for finding a variable
Find the corresponding attribute in the execution context under the current scope. If there is a direct return, otherwise enter 2
Find the corresponding attribute in the execution context of the upper level scope. If there is a direct return, otherwise enter 3
Perform the same operation of 2 again until the global scope. If it is not found, throw an exception that cannot be found (xxx is not defined)
var a = 1; function fn1() { var b = 2; function fn2() { var c = 3; console.log(c); // 3 console.log(b); // 2 console.log(a); // 1 console.log(d); // Error d is not defined } fn2(); } fn1();
4, Closure
Example: realize the button cycle to listen for events. Click the corresponding button to pop up the first one
<body> <button>Test 1</button> <button>Test 2</button> <button>Test 3</button> <script type="text/javascript"> var btns = document.getElementsByTagName('button'); // Traversal plus listening /* This method cannot correctly pop up the value corresponding to the button, because i is a variable in the global scope. After the for loop binds the event, click the execute event function. In the function, i accesses the external global variable, and at this time, the value of i is the value after the loop for (var i = 0,lengths = btns.length; i < lengths; i++) { var btn = btns[i]; btn.onclick = function() { alert('The '+ (i + 1) +' th '); } }*/ /* Save subscript to button for (var i = 0,lengths = btns.length; i < lengths; i++) { var btn = btns[i]; btn.index = i; // Save the subscript corresponding to btn to btn btn.onclick = function() { alert('The '+ (this.index + 1) +' number '); } }*/ // Using closures for (var i = 0,lengths = btns.length; i < lengths; i++) { (function(i) { var btn = btns[i]; btn.onclick = function() { alert('The first' + (this.index + 1) + 'individual'); } })(i); } </script> </body>
understand
How to generate closures?
Closure occurs when a nested inner (child) function references a variable (function) of a nested outer (parent) function
What is a closure?
Closures are nested internal functions that contain objects that are referenced by external variables (functions)
Conditions for generating closures?
The function is nested, and the internal function references the data of the external function (variable / function)
As shown in the above figure, you can view closures through the chrome debugging mode. Closure s are generated when the internal function definition is executed (not the calling function). To execute the internal function definition, you need to call the external function first, and you don't need to call the internal function.
Common closures
1. Take a function as the return value of another function
function fn1() { var a= 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); // A closure is generated by calling an external function here f(); // Output 3 f(); // Output 4
2. Pass a function as an argument to another function call
function fn(msg, time) { setTimeout(function() { alert(msg); }, time); } fn('msg', 2000);
Function of closure
The variables inside the function still exist in memory after the function is executed (prolonging the declaration cycle of local variables)
Data (variable / function) that can be manipulated (read and write) outside the function to the inside of the function
// The following code extends the life cycle of variable A. when fn1 is executed, fn2 and fn3 generate closures. By returning fn2 or fn3 and receiving the call, the operation of adding or subtracting 1 to variable a can be realized, and no other operation can be performed on variable a except addition and subtraction. function fn1() { var a = 2; function fn2() { a++; console.log(a); } function fn3() { a--; console.log(a); } return fn3; } var f = fn1(); f();
problem
1. After the function is executed, does the local variable declared inside the function still exist?
Generally, it does not exist. Only variables that exist in closures can exist
function fn1() { var a = 2; function fn2() { a++; console.log(a); } function fn3() { a--; console.log(a); } return fn3; } var f = fn1(); // fn1 will be released after the function is executed. Here, fn3 is returned, which is referenced by variable f. So the inner function fn3 is not released. // fn1(); If there is no reference here, it will become a garbage object and be released after execution. f();
2. Can local variables inside a function be accessed directly outside the function?
No, but we can let the outside operate it indirectly through closures. For example, as shown in the code above.
Closure lifecycle
1. Generate: generated when the nested internal function definition is executed (not called)
2. Death: when a nested inner function becomes a garbage object
function fn1() { // At this point, the closure has been generated (function promotion, internal function object has been created) var a = 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); f(); f(); f = null; // Closure death (function objects containing closures become garbage objects)
Application of closures: defining JS modules
JS module:
js files with specific functions
Encapsulate all data and functions inside a function (private)
Expose only one object or function containing n methods
The user of the module only needs to call the method through the exposed object of the module to realize the corresponding function
// myModule.js function myModule() { // Private data var msg = 'My Module'; // Functions that manipulate data function doSomethiing() { console.log('doSomething()', msg.toUpperCase()); } function doOtherthing() { console.log('doOtherthing()', msg.toLowerCase()); } // Expose objects outward (Methods for external use) return { doSomethiing: doSomethiing, doOtherthing: doOtherthing } }
<!-- index.html --> <!doctype html> <html class="no-js" lang=""> <head> <meta charset="utf-8"> <title></title> </head> <body> </body> <script type="text/javascript" src="js/myModule.js"></script> <script type="text/javascript"> var module = myModule(); module.doSomethiing(); module.doOtherthing(); </script> </html>
On the other hand, assign the content to be exposed to the window. As follows:
(function myModule2() { // Private data var msg = 'My Module'; // Functions that manipulate data function doSomethiing() { console.log('doSomething()', msg.toUpperCase()); } function doOtherthing() { console.log('doOtherthing()', msg.toLowerCase()); } // Expose objects to the outside (Methods for external use) objects to be exposed to the window window.myModule2 = { doSomethiing: doSomethiing, doOtherthing: doOtherthing } })();
<!-- index.html --> <!doctype html> <html class="no-js" lang=""> <head> <meta charset="utf-8"> <title></title> </head> <body> </body> <script type="text/javascript" src="js/myModule2.js"></script> <script type="text/javascript"> myModule2.doSomethiing(); myModule2.doOtherthing(); </script> </html>
Disadvantages of closures
1. Shortcomings
After the function is executed, the local variables in the function are not released, and the memory consumption time will become longer
Easy to cause memory leakage
2. Settle
You don't have to close it
Timely release
<script type="text/javascript"> function fn1() { var arr = new Array[10000000]; function fn2() { console.log(arr.length); } return fn2; } var f = fn1(); f(); f = null; // Make internal functions garbage objects -- > recycle closures </script>
supplement
out of memory
An error in the operation of a program
When the program needs more memory than the remaining memory, it will throw a memory overflow error
Memory leak
The occupied memory is not released in time
Memory leaks accumulate too much, which can easily lead to memory overflow
Common memory leaks:
Unexpected global variable
Timer or callback function not cleaned in time
closure
// Unexpected global variable function fn() { a = new Array(100000000); // var is not used to define local variables, resulting in a becoming an unexpected global variable. } fn(); // Timer or callback function not cleaned in time var intervalId = setInterval(function() { console.log('------------'); }, 1000); // The timer is not cleaned after use // clearInteval(intervalId); // closure function fn1() { var a = 4; function fn2() { console.log('---', a); } return fn2; } var f = fn1(); f(); // Closure not cleaned after use // f = null;
5, Object oriented advanced
Object creation mode
Mode 1: Object constructor mode
Routine: first create an empty Object object, and then dynamically add attributes / methods
Applicable scenario: uncertain object internal data at the beginning
Problem: too many statements
var p = new Object(); p.name = 'Tom'; p.age = 12; p.setName = function(name) { this.name = name; } p.setName('JACK'); console.log(p.name, p.age);
Method 2: object literal mode
Routine: create objects with {} and specify properties / methods
Applicable scenario: at the beginning, the internal data of the object is determined
Problem: if you create multiple objects, there is duplicate code
var p = { name: 'Tom', age: 12, setName: function(name) { this.name = name; } } // test console.log(p.name, p.age); p.setName('JACK'); console.log(p.name, p.age); var p2 = { // If you create multiple objects, the code is repetitive name: 'Bob', age: 13, setName: function(name) { this.name = name; } }
Mode 3: factory mode
Routine: dynamically create objects through factory functions and return
Applicable scenario: multiple objects need to be created
Problem: objects don't have a specific type, they are all objects
function createPerson(name, age) { var obj = { name: name, age: age, setName: function(name) { this.name = name; } } return obj; } // Create two objects var p1 = createPerson('Tom', 12); var p2 = createPerson('Bob', 13); function createStudent(name, price) { var obj = { name: name, price: price } return obj; } var s = createStudent('Zhang San', 12000); // Here p1, p2 and s are also Object types. So the Object does not have a specific type.
Method 4: Custom constructor mode
Routine: Custom constructor, create object through new
Applicable scenario: you need to create multiple objects with certain types
Problem: each object has the same data, which wastes memory
// Define type function Person(name, age) { this.name = name; this.age = age; this.setName = function(name) { this.name = name; } } var p1 = new Person('Tom', 13); p1.setName('Jack'); console.log(p1.name, p1.age); console.log(p1 instanceof Person);// true function Studen(name, price) { this.name = name; this.price = price; this.setName = function(name) { this.name = name; } } var s1 = new Studen('KC', 1200); s1.setName('KAKA'); console.log(s1.name, s1.price); console.log(s2 instanceof Studen);// true here and quilted p1 have their own types
Mode 5: combination mode of constructor + prototype
Routine: Custom constructor, property initialized in function, method added to prototype
Applicable scenario: you need to create multiple objects with certain types
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.setName = function(name) { // Put the method into the prototype this.name = name; } var p1 = new Person('Tom', 12); var p2 = new Person('Bob', 13); p1.setName('JACK'); // p1 and p2 have their own attributes, and the method is on the prototype. Their prototype is the same, so they share a method
Prototype chain inheritance
tricks:
Define a parent type constructor
Add a method to the prototype of the parent type
Defines the constructor for the subtype
Create an object of the parent type and assign it to the prototype of the child type
Set the constructor property of the subtype prototype to the bit subtype
Adding methods to subtype prototypes
Create sub type objects: you can call methods of the parent type
Key:
The prototype of the subtype is an instance object of the parent type
// Parent type function Supper() { this.supProp = 'Supper property'; } Supper.prototype.showSupperProp = function() { console.log(this.supProp); } // Subtype function Sub() { this.subProp = 'Sub property'; } // The prototype of the subtype is an instance object of the parent type Sub.prototype = new Supper(); Sub.prototype.showSubProp = function() { console.log(this.subProp); } var sub - new Sub(); sub.showSupperProp(); sub.showSubProp();
Borrowing constructor inheritance (false)
tricks:
Define a parent type constructor
Define subtype constructor
Calling parent type constructor in subtype constructor
Key:
In the subtype constructor, call call() to call the parent type constructor.
function Person(name, age) { this.name = name; this.age = age; } function Student(name, age, price) { Person.call(this, name, age); // Equivalent to: this Person(name, age); this.price = price; } var s = new Student('Tom', 20, 10000); console.log(s.name, s.age, s.price);
*Combinatorial inheritance
Combined inheritance of prototype chain + borrowing constructor
Using prototype chain to realize method inheritance of parent type object
Use super() to borrow the parent type to build the function to initialize the same attribute
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.setName = function(name) { this.name = name; } function Student(name, age, price) { Person.call(this, name, age); // To get the parent type attribute this.price = price; } Student.prototype = new Person(); // In order to see the methods of the parent type Student.prototype.constructor = Student; // Fix the contractor property Student.prototype.setPrice = function(price) { this.price = price; } // test var s = new Student('Tom', 24, 15000); s.setName('Bob'); s.setPrice(11100); console.log(s.name, s.age, s.price);
6, Thread mechanism and event mechanism
Process and thread
process
An execution of a program, which occupies a unique memory space
You can view the process through the window task manager
thread
A thread is an independent execution unit within a process
It is a complete process of program execution
It is the smallest scheduling unit of CPU
Relevant knowledge
The application cannot run on a thread of a process
There is at least one running thread in a process: the main thread, which is automatically created after the process is started
A process can run multiple threads at the same time. We will say that the program runs in multiple threads
The data in a process can be directly shared by multiple threads
Data between multiple processes cannot be shared directly
thread pool: a container for storing multiple thread objects to realize the repeated utilization of Thread objects
Related issues
What is multiprocessing and multithreading?
Multi process running: an application can start multiple instances at the same time
Multithreading: multiple threads run simultaneously in a process
Single thread and multi thread
Multithreading:
advantage:
It can effectively improve the utilization of CPU
Disadvantages:
Create multithreading overhead
Inter thread switching overhead
Deadlock and state synchronization
Single thread:
Advantages: sequential programming is simple and easy to understand
Disadvantages: low operation efficiency
Is JS single threaded or multi-threaded?
JS is single threaded
However, wokers can run in multiple threads through the web in H5
Is browser runtime multithreaded or single threaded?
Multithreading
Browser runtime single process or multi process?
Sometimes single process:
firefox, old IE
Sometimes multiple processes:
chrome, new IE
You can check the task manager of window when the program is running to determine whether it is a multi process or a single process
Browser kernel
The browser kernel is the core program that supports the operation of the browser
Different browsers may be different. For example, chrome and Safrai use webkit, firefox uses Gecko, IE uses Trident, and 360, Sogou and other domestic browsers use Trident+webkit
The kernel consists of many modules:
Main thread:
js engine module: responsible for compiling and running js programs
html and css document parsing module: responsible for parsing the page text
DOM / CSS module: responsible for the processing of DOM / CSS in memory
Layout and rendering module: responsible for the layout of the page and the rendering of the effect (objects in memory)
Split thread:
Timer module: responsible for timer management
DOM event response module: responsible for event management
Network request module: responsible for ajax request
Other modules:
Thinking caused by timer
Is the timer really timed?
Timers do not guarantee real timing
Generally, there will be a slight delay (acceptable range), but it may also be a long delay (unacceptable range)
Is the timer callback function executed in threads?
js is single threaded when executed by the main thread
How is the timer implemented?
Event cycle model
<button id='btn'> Start timer </button> <script type="text/javascript"> document.getElementById('btn').onclick = function() { var start = Date.now(); console.log('Before starting the timer...') setTimeout(function() { console.log('The timer is running', Date.now() - start); }, 200); console.log('After starting the timer...') // Following a long time will delay the timer for a long time (unacceptable range) for(var i = 0; i < 1000000; i++) { // Extended timer execution by long cycle } } </script>
Single thread JS
1. How to prove that js execution is single threaded?
The callback function of setTimeout() is executed in the main thread
The timer returns to the function, which can be executed only after all the code in the run stack is executed
2. Why should js use single thread mode instead of multi thread mode?
The single thread of JavaScript is related to its purpose
As a browser scripting language, JavaScript is mainly used to interact with users to operate DOM
This determines that it can only be a single thread, otherwise it will bring complex synchronization problems
3. Classification of codes
setup code
callback code
4. The basic process of executing code by js engine
Execute initialization code first: contains some special code callback functions (asynchronous execution)
set timer
Binding event listening
Send ajax request
The callback code will be executed at a later time
setTimeout(function() { console.log('timeout 2000') }, 2000); setTimeout(function() { console.log('timeout 1000'); alert('1000'); }, 1000); setTimeout(function() { console.log('timeout 0'); }, 0); function fn() { console.log('fn()'); } fn(); console.log('alert()before'); alert('--------'); // Pause the execution of the current main thread and pause the timing at the same time. Click OK to resume the program execution and timer console.log('alert()after'); /* Execution sequence: fn() alert()before Pop up alert and click OK alert()after timeout 0 One second later: timeout 1000 alert 1000 pops up and click OK One second later: timeout 2000 */
Event cycle model
1. All code categories
Initialization execution code (synchronization code): including the code for binding dom event listening, setting timer and sending ajax request
Callback execution code (asynchronous code): handles callback logic
2. Basic process code of js engine:
Initialization code = = > callback code
3. Two important components of the model:
Event (timer / DOM event / Ajax) management module
Callback queue
4. Operation process of model
Execute the initialization code and hand over the event callback function to the corresponding module for management
When the event is sent, the management module will add the function and its data to the callback queue
Only after the initialization code is executed (it may take some time), the callback function in the read callback queue will be traversed and executed
<button id='btn'> test </button> <script type="text/javascript"> function fn1() { console.log('fn1()'); } fn1(); document.getElementById('btn').onclick = function() { console.log('Click btn'); } setTimeout(function() { console.log('The timer is running'); }, 2000); function fn2() { console.log('fn2()'); } fn2(); </script> <!-- Execution sequence: fn1() fn2() The sequence of timer and button is uncertain -->
Web Workers
H5 specification provides the implementation of js sub threading, which is called Web Workers
Related API:
Worker: constructor, which loads the js file executed by threads
Worker.prototype.onmessage: callback function used to receive another thread
Worker.prototype.postMessage: Send a message to another thread
Insufficient:
Code in Worker cannot operate DOM (update UI)
JS cannot be loaded across domains
Not every browser supports this new feature
Practical application of Web Workers:
<!-- Use recursion to calculate the value of the Fibonacci sequence where the input number is located --> <!-- In this calculation method, when the number of calculation bits is large, the whole interface will be inoperable and wait for the calculation result. The main thread has been calculating --> <input type="text" placeholder="numerical value" id="number" /> <button id='btn'> calculation </button> <script type="text/javascript"> function fibonacci(n) { return n <= 2 ? 1 :fibonacci(n-1) + fibonacci(n-2); // Recursive call } var input = document.getElementById('number'); document.getElementById('btn').onclick = function() { var number = input.value; var result = fibonacci(number); alert(result); } </script>
The solution using Web Workers is as follows: (you need to start in the container to pass the test)
<input type="text" placeholder="numerical value" id="number" /> <button id='btn'> calculation </button> <script type="text/javascript"> var input = document.getElementById('number'); document.getElementById('btn').onclick = function () { var number = input.value; // Create a Worker object var worker = new Worker('myWorker.js'); // Send messages to threads worker.postMessage(number); // Bind listening for receiving messages worker.onmessage = function (event) { console.log('The main thread receives the data returned by the sealing thread', event.data); alert(event.data); } } </script>
// myWorker.js function fibonacci(n) { return n <= 2 ? 1 : fibonacci(n-1) + fibonacci(n-2); // Recursive call } var onmessage = function(event) { var number = event.data; console.log('The sub thread receives the data sent by the main thread:', number); // calculation var result = fibonacci(number); postMessage(result); // alert(result); alert is a method of window, which cannot be called in sub thread // console is implemented by browser, so it can be used // Each thread has its own global object // The global object in the sub thread is no longer window, so it is impossible to follow the new interface in the sub thread }
Insufficient workers:
1. Slow speed 2. js cannot be loaded across domains 3. Not every browser supports this new feature 4. Code in worker cannot access DOM (update)