preface:
This note is an advanced self-study note of javascript based on JavaScript. The full text is about 11000 words
Main contents:
- Depth of data types;
- Prototype chain;
- Succession;
Parts to be improved:
- Combinatorial inheritance, combinatorial + parasitic inheritance;
- Browser thread;
Last updated on: August 3, 2021
data type
Basic type
string
number
boolean
undefined
null
Reference type (object type)
object
Function (special object, executable)
Array (special object, internal data in order)
Judge data type
typeof
Returns a string of data type
Unable to judge null and object, both return object
Neither array nor object can be judged. Both return object
Instanceof (instance)
Determine the specific type of reference type
The output is Boolean
a instanceof Object/Function/Array
Functions and arrays are also objects
===
Can be used to determine undefined and null
What is the difference between undefined and null?
undefined means that an unassigned value is defined
Null means defined and assigned, and the value is null
When is a variable assigned null?
The initial assignment is null, indicating that it will be assigned as an object
var a = null // Indicates the object to be assigned a = [] a = null // Free memory occupied by array
Finally, assign null to change the pointing object into a garbage object, so that it can be recycled and free memory
Strictly distinguish between data types and variable types
Type of variable (type of variable memory value)
Basic type: the saved value is a basic type
Reference type: the saved value is the address of the object
Variable parameter passing is value passing. The value may be the basic type or the address value of the object
Note the following distinction: the saved address value and the object pointed to
var a = { // Give the address value of the object to a // The object itself is in the heap, and the address value identifying the object is saved on the stack age: 12 } function changeAge(a) { a.age = 17; } changeAge(a); // A and parameter a in the function have different addresses and point to the same object // The same object is modified console.log(a.age);// 17
var a = { // Give the address value of the object to a // The object itself is in the heap, and the address value identifying the object is saved on the stack age: 12 } function changeAge(a) { // The formal parameter of the function originally points to the same object as the uppermost a, that is, age=12 a = {age: 17}; // At this time, the formal parameter of the function points to the new object age=17 // The real a is another object and has not changed } changeAge(a);// Assign a to a formal parameter console.log(a.age);// 12
Note: if you use const to declare an object, you cannot change it to another object
var a = 3 function add(a) { a = a + 1; console.log(a);// 4 } add(a);// The function passes data 3 console.log(a);// 3 // Understand according to the variable scope
How does the JS engine manage memory
Life cycle of memory
1. Allocate memory and obtain usage rights
2. Data can be stored for repeated operation
3. Free memory space
Free memory
1. Local variable: the function is automatically released after execution. Pay attention to different closures
2. Object: become a garbage Object > garbage collector collection
object
Method is a special property
The property value is the method of the function
When do I have to read or modify an object's properties by using [property name]?
The attribute name wrapped with [] should be quoted to indicate that it is a string
Variables are represented without quotation marks
1. The property name contains special characters: - spaces
var p = {} // p.a-b = 'aaa';// error p['a-b'] = 'aaa'; console.log(p['a-b']);// aaa
2. The property name is variable
var p ={} var a1 = 'myAge'; var value = 18; // p.a1 = value; // console.log(p); // Output a1: 18 instead of myAge: 18 // a1 should be a variable that holds the attribute name p[a1] = value; console.log(p); // Output myAge: 18
function
Function is the encapsulation of n statements, which is convenient for reuse
Only functions can be executed, and other data cannot be executed
Improve code reuse and facilitate reading and communication
fun1(); // fun2(); // error // Function declaration method // Can be used in advance function fun1() { console.log('Hello'); } fun1(); // Define functions in expression mode // You can't use it in advance var fun2 = function(){ console.log('Expression mode'); } fun2();
var obj1 = {} function fun3(){ console.log('Your mother'); } // You can call a function as a method that specifies any object fun3.call(obj1);// By function Call (object) causes the function to be called again by a method called an object
Callback function
DOM event callback function
var btn = document.querySelector('button'); btn.addEventListener('click',function(){ // Get text dynamically alert(this.innerHTML); })
Timer callback function
setTimeout(function(){ alert(123456); },2000)
Network request callback function
Later
Lifecycle callback function
Later
IIFE
immediately invoked function expression
Execute the function immediately, and the anonymous function calls itself
(function (){ var a= 3; console.log(a+2); })(); // ES6 ((a=3) => console.log(a+2))()
Function: hide the implementation, do not pollute the global namespace, and write JS modules
this
Every time the parser calls a function, it will pass an implicit parameter into the function. This implicit parameter is this, which points to an object
This object is called the context object of function execution. Depending on the calling method of the function, this will point to different objects
1. When called as a function, this is always window
2. When called as a method, this is the object that calls the method
3. When called in the form of constructor, this is the newly created object (instance)
4. When call () and apply() are used, this is the specified object
5. In the event response function, this is who the response function is bound to
Function advanced
Prototype and prototype chain (the implicit prototype of the instance object points to the explicit prototype of its constructor)
The prototype property of the function
Each function has a prototype attribute, which by default points to an empty object, the (explicit) prototype object
The prototype object has a property called constructor (constructor), which points to itself (constructor object)
The constructor and its own prototype object refer to each other
console.log(fun1.prototype.constructor === fun1); // true
Add properties (usually methods) to prototype objects
Role: all instance objects automatically own properties (Methods) in the prototype
function fun1(){ } // Each function has a prototype attribute // Function name A prototype is an object // js can dynamically add attributes to objects // Add a method fun1.prototype.test = function(){ console.log('test()'); } console.log(fun1.prototype);
Explicit prototype and implicit prototype
Each function has a prototype attribute, that is, an explicit prototype, which points to an empty object (instance object) by default Automatically add when defining a function
Each instance object has one__ proto__ Property, that is, the implicit prototype, is automatically added when the instance object is created,
The implicit prototype of the instance object points to the value of the display prototype of its corresponding constructor
(↑ important!!)
function Fn(){ } console.log(Fn.prototype); var fn = new Fn(); console.log(fn.__proto__); console.log(Fn.prototype === fn__proto__);// true
// Create function object // Fn is the variable name, which stores the address value of the object function Fn(){ this.test1 = function(){ console.log('test1'); } } console.log(Fn.prototype); // Each function has a prototype attribute, that is, to display the prototype. By default, it points to an empty Object (prototype Object) // Add a method test2 to the prototype object Fn.prototype.test2 = function(){ console.log('test2'); } var fn = new Fn()
The value of the explicit prototype of the constructor object is equal to the value of the implicit prototype of the instance object
Prototype chain (implicit prototype chain)
When accessing the properties of an instance object
1. First find the attribute of the instance object and find the returned value
2. Otherwise, follow the path of the instance object__ proto__ Look up, find and return
3. Otherwise, return undefined
be careful:
1. All functions are instances of Function (including Function itself)
2. The prototype object of object is the end of the prototype chain
Setting and finding
Search is generally to find yourself first, and if you don't, you can trace the source along the prototype chain
But the settings are set directly on yourself
function Fn() {} // Add attribute a:'jjj' on prototype object Fn.prototype.a = 'jjj' const fn1 = new Fn() const fn2 = new Fn() fn2.a = 'yyy' console.log(fn1.a,fn1); // Find whether it has a, if not, find it along the prototype chain (implicit prototype - explicit prototype - prototype object) // jjj console.log(fn2.a,fn2); // When setting properties for an instance, they are directly set to the instance itself // yyy
Prototype inheritance
The instance object of the constructor automatically owns the properties and methods of the constructor prototype object
Detailed explanation of instanceof
A instanceof B
That is, judge whether A is an instance of B
Returns true if the explicit prototype object of the B constructor is on the implicit prototype chain of the A instance object, otherwise returns false
const arr = [] console.log(arr instanceof Array);// true console.log(arr instanceof Object);// true const fn = () => {} console.log(fn instanceof Function);// true console.log(fn instanceof Object);// true // const Ff = () => {} // Let's review the implementation process of new: // 1. Create an empty object // 2. The object's__ proto__ prototype that points to a constructor, such as Fn // 3. Modify the context of the constructor Fn to an empty object // 4. Returns an empty object (actually this) // The arrow function does not meet the second step, that is, there is no prototype, so you cannot use the new keyword to create an instance object of the arrow function function Ff(){} const ff = new Ff console.log(ff); console.log(ff instanceof Ff);// true console.log(ff instanceof Function);// false // Because there is no Function on the prototype chain of the ff instance object // ff.__proto__ === Ff.prototype → object // object.__proto__ === Object.prototype // Object.__proto__ === null (end of prototype chain) // It can be seen that there is no Function in the middle console.log(ff instanceof Object);// true console.log(Ff.prototype instanceof Object);// true console.log(ff.__proto__ instanceof Object);// true console.log(Object instanceof Function);// true console.log(Object instanceof Object);// true console.log(Function instanceof Function);// true console.log(Function instanceof Object);// true function Fun(){} console.log(Object instanceof Fun);// false
Own thinking
The so-called = = = and pointing actually have the same meaning, because both the implicit prototype of the instance object and the display prototype of the constructor are saved address values, and the address values are all equal. It can also be said that the implicit prototype points to the display prototype, and the display prototype points to the prototype object (an object)
Prototype topic
1
// Create constructor var A = function(){} // Add the attribute n to the instance object and assign a value of 1 A.prototype.n = 1; // Create instance object var b = new A(); // At this point, the display prototype of the constructor points to the new prototype object (address change) A.prototype = { n:2, m:3 } var c = new A(); console.log(b.n,b.m,c.n,c.m); // 1 undefined 2 3
2
// Define function var F = function(){} // Add a method to the Object prototype Object.prototype.a = function(){ console.log('a()'); } // Add b method to Function prototype Function.prototype.b = function(){ console.log('b()'); } var f = new F(); f.a() // a() f.b()// error F.a()// a() F.b()// b() // Note: this section understands the prototype chain diagram
Prototype chain diagram
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-YTl3HlO5-1627938283454)(./images/js advanced / SRC = http__ img2018.cnblogs.com_blog_1762947_201909_1762947-20190926094156327-588943618. JPG & refer = http__ img2018. Cnblogs. JPG)]
Variable declaration promotion
var is declared in advance but not assigned. It is assigned only after execution, and the access before execution is undefined
Both const and let in ES6 do not have variable promotion. There is a dead zone before declaration. If you use variables, you will report an error
Function declaration promotion
function is declared in advance and can be called directly
Function promotion must be declared
function fun(){}
Global execution context
1. Determine the window as the global execution context before executing the global code
2. Pre parse global data
The global variable defined by var is undefined and added as the attribute of window
Assignment of global function declared by function and added as the method of window
this is assigned to window
3. Start executing global code
Function execution context
1. Before calling the function and preparing to execute the function body, create the corresponding function execution context object
2. Pre analyze local data
Formal parameter variable → assignment (argument) → attribute added as execution context
arguments → assignment (pseudo array of all argument lists) → attribute added as execution context
Defined local variable → assign undefined and add it as the attribute of the execution context
Function declared function → assignment, added as the method of execution context
this → assignment
3. Start executing function code
var c = 1; function C(c) { console.log(c);// Output passed argument 3 var c = 2;// Declared advance value undefined } C(3); // 3
Execution Context Stack
1. Before global code execution, JS engine will create a stack to store and manage all execution context objects
2. After the global execution context (window) is determined, add it to the stack for stack pressing
3. After the function execution context is created, add it to the stack for stack pressing
4. After the current function is executed, remove the stack top object and exit the stack
5. After all the code is executed, only window remains in the stack
Example 1
var i = 1; fun(1);// Function declaration is called directly in advance function fun(i){ if(i == 4){ return; } console.log(i); fun(i+1);// Recursive call console.log(i); } console.log(i); // 1 2 3 | 3 2 1 1
Example 2
function a(){} var a; console.log(typeof a); // function // Perform variable promotion before function promotion
Example 3
if (!(b in window)) { var b = 1; } console.log(b); // undefined
Example 4
var c = 1; function c(c){ console.log(c); var c = 3; } c(2); // error // amount to var c;// Variable promotion // Function promotion function c(c){ console.log(c); var c = 3; } // Variable assignment c = 1; // At this time, c is not a function, so an error is reported c(2);
Scope and scope chain
Scope
The area where the code segment is located. It is static and is determined when writing code
Classification: global scope, function scope, ES6 block level scope
Scope: isolate variables. Variables with the same name under different scopes will not conflict
Scope and execution context
Difference 1:
Outside the global scope, each function will create its own scope. The scope has been determined when the function is defined, not when the function is called
The global execution context is created immediately after the global scope is determined and before the js code is executed
The function execution context is created before the function body code is executed when the function is called
Difference 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 a function is called. At the end of a function call, the execution context is out of the stack and released
Contact:
The execution context is subordinate to the scope in which it resides
Example 1
let x = 10 function fn(){ console.log(x); } function show(f){ let x = 20 f() // Note that executing f() at this time will find x in the local scope of fn function // Global x = 10 not found along scope chain } show(fn) // 10
Example 2
const obj = { fn(){ console.log(fn); } } obj.fn() // report errors // The {} of obj does not form a layer of scope. Outside the function, it is directly global, and there is no fn in the global
closure
// Pop up message box corresponding to implementation button var btns = document.querySelectorAll('button'); // closure for (var i = 0; i < btns.length; i++) { (function (i) { var btn = btns[i]; btn.onclick = function () { alert('The first' + (i + 1) + 'individual'); } })(i); } // for (var i = 0; i < btns.length; i++) { // var btn = btns[i]; // btn.index = i; // btn.onclick = function () { // alert('the '+ (this.index + 1) +' number '); // } // }
How to generate closures?
When the nested internal child function references the variable (or function) of the external parent function, the execution of the external parent function generates closures. The execution of the external function several times generates several closures
What is a closure?
Closures are the nested internal sub functions mentioned above, and their references to external function variables or functions are called closures as a whole
Closures are functions that can read internal variables of other functions—— Ruan Yifeng
Function of closure
1. Use the variables inside the function to survive in memory after the function is executed (prolonging the life cycle of local variables)
2. Data (variable / function) that can be manipulated (read / write) from outside the function to inside the function
3. Encapsulate private data and some functional functions into the same function, and then expose them to the outside to form an independent functional module
Shortcomings and solutions of closures: memory overflow and memory leak
Because the local variables used in closures will always exist, they cannot be released
Release the nested function object in time to make it a garbage object and be recycled
function fun(n, o) { console.log(o) return { fun: function (m) { return fun(m, n) } } } var a = fun(0) //undefined a.fun(1) //0 a.fun(2) //0 a.fun(3) //0 var b = fun(0).fun(1).fun(2).fun(3) // undefined 0 1 2 var c = fun(0).fun(1) // undefined 0 c.fun(2) //1 c.fun(3) //1
Object advanced
new Object() constructor pattern
Object literals are created using {}
Factory mode
Disadvantages: objects have no specific type, they are all objects
function Person (name,age) { const obj = { name:name, age:age, setName:function(){ this.name = name } } return obj } const p1 = new Person('jrj',16) const p2 = new Person('Bob',22) console.log(p1);
Custom constructor mode
Different objects have specific types
console.log(p1 instanceof Person);
function Person(name, age) { this.name = name this.age = age this.setName = function (name) { this.name = name } } const p1 = new Person('jrj', 16) const p2 = new Person('Bob', 22) p2.setName('HHH') console.log(p1) console.log(p2);;
Constructor + prototype
Put the method on a common prototype
function Person(name, age) { // Only general properties are initialized in the constructor this.name = name this.age = age } Person.prototype.setName = function (name) { this.name = name } const p1 = new Person('jrj', 16) const p2 = new Person('Bob', 22) p2.setName('HHH') console.log(p1) console.log(p2)
Inheritance mode
1. Prototype chain inheritance
The prototype object of the subtype should be an instance object of the parent type
function Father() { this.fatherProp = 'father' } Father.prototype.showFatherProp = function () { console.log(this.fatherProp); } function Son() { this.sonProp = 'son' } // To implement prototype chain inheritance // The prototype object of the subtype should be an instance object of the parent type Son.prototype = new Father() const s1 = new Son() s1.showFatherProp()// 'Father' console.log(s1.__proto__ === Son.prototype);// true console.log(Son.prototype.__proto__ === Father.prototype); // true
2. Borrow constructor
That is, the subclass calls the properties and methods of the parent class through js apply and call;
The prototype chain method can realize the sharing of all attribute methods, but it cannot achieve attribute Method exclusive (for example, Sub1 modifies the function of the parent class, and all other subclasses Sub2 and Sub3... Cannot be implemented if they want to call the old function); while the borrowing constructor can not only enjoy the properties and methods, but also pass parameters in the subclass constructor, but the code cannot be reused. Generally speaking, all properties and methods can be exclusive, but the properties and methods cannot be shared (for example, Sub1 adds a function, and if you want Sub2 and Sub3... To work, you can't implement it. You can only add Sub2 and Sub3... In the constructor respectively)
3. Combinatorial inheritance
Combined above
4. Optimal solution: parasitism + combinatorial inheritance
To be continued
Process and thread
imperfect
process
An execution of a program, which occupies a unique memory space
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 must run on a thread of a process
There is at least one running thread in a process: the main thread, which will be created automatically after the process is started
A process can also 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 the threads in it
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
JS is single threaded
However, using Web Workers in H5 can run in multiple threads
Advantages and disadvantages of single thread / multithreading
Multithreading
advantage:
- Effectively improve CPU efficiency
Disadvantages:
- Create multithreading overhead
- Thread switching overhead
- Deadlock and state synchronization problems
Single thread
advantage:
- Sequential coding is easy to understand
Disadvantages:
- Low efficiency
Browsers are multithreaded
But some are single process (Firefox old IE)
There are many processes (Chrome new IE)
Browser kernel
The browser kernel consists of multiple modules
Chrome | Safari : webkit
firefox: Gecko
IE : Trident
Domestic: Trident + webkit
Main thread
JS engine thread
Responsible for compiling and running JS program
GUI rendering thread
Responsible for rendering browser interface, parsing HTML and CSS, building DOM tree and RenderObject tree, layout and rendering, etc.
When the interface needs to be repainted or reflow is caused by some operation, the thread will execute
Note that the GUI rendering thread and the JS engine thread are mutually exclusive. When the JS engine executes, the GUI thread will be suspended (equivalent to being frozen), and the GUI update will be saved in a queue and executed immediately when the JS engine is idle.
GUI rendering thread and JavaScript engine thread are mutually exclusive!
Because JavaScript can manipulate DOM, If you render the interface while modifying these element attributes (that is, the JavaScript thread and UI thread run at the same time), then the element data obtained before and after the rendering thread may be inconsistent. Therefore, in order to prevent unexpected results in rendering, the browser sets the GUI rendering thread and the JavaScript engine as mutually exclusive. When the JavaScript engine executes, the GUI thread will be suspended, and the GUI update will be saved in a queue until the engine The thread is executed immediately when it is idle. This is why the < script > tag should be placed at the bottom of the body tag.
Sub thread
Timer thread
Responsible for timer management
DOM event response thread
Responsible for DOM event management
Network request thread
Such as Ajax request
The basic process of executing code by JS engine
Execute the initialization code first, including some special codes, such as setting the timer, binding event listening, and sending AJAX requests
The callback code will be executed at a later time
H5 Web Workers multithreading
H5 specification provides the implementation of JS threading, which is called Web Workers
We can run some large amount of code by Web Workers without freezing the user interface
However, the child thread is completely controlled by the main thread and cannot operate DOM. The global object of the worker is not window
So this new standard does not change the single threaded nature of JavaScript
Cannot cross domain
Not all browsers support