2021 autumn recruit review - Javascript

data type

Basic data type

  1. null
  2. undefined
  3. number
  4. string
  5. boolean

Reference data type

  1. object
    • array
    • function
    • date
  2. Symbol (introduced by ES6)

Method of detecting data type

  1. typeof

    typeof [1,2]  // object
    
  2. instanceof

    [1,2] instanceof Array  // true
    

function

Declarative definition function

Expression definition function (anonymous function)

Arrow function (es6)

characteristic:

  1. The arrow function does not have its own this object. This points to this in the execution context when it is created;
  2. Cannot be used as a constructor;
  3. arguments object is not allowed
  4. Not available. Use the yield command

this point

call,apply,bind

Variable, scope

Variable definition

  • var

    There are variable promotion and temporary deadband

  • let,const(es6)

    Block level scopes are introduced

Scope

The scope is the variable object (VO) / active object (AO) in the global execution context and local execution context

Scope chain

When code is executed in an environment, a scope chain of variable objects will be created to ensure orderly access to variables and functions that the execution environment has access to.

Prototype, prototype chain

Relationship between constructors, prototypes, and instances

Each constructor has a prototype object, the prototype object contains a pointer to the constructor, and the instance contains an internal pointer to the prototype object.

Basic concepts of prototype chain

Make the prototype object equal to an instance of another type. At this time, the prototype object will contain a pointer to another prototype object, and the other prototype also contains a pointer to another constructor. If another prototype is an instance of another prototype, then the above relationship is still established. In this way, it constitutes the chain between the instance and the prototype. This is the basic concept of the so-called prototype chain.

Prototype chain inheritance

// Prototype chain inheritance
function SuperType(){
	this.property = true;
}
		
SuperType.prototype.getSuperValue = function(){
	return this.property;
}
		
function SubType(){
	this.subproperty = false;
}
		
// Inherited SuperType
SubType.prototype = new SuperType();
		
SubType.prototype.getSubValue = function(){
	return this.subproperty;
}
		
var instance= new SubType();
console.log(instance.getSuperValue());  // true

The problem of prototype chain inheritance

  1. When there is a reference type attribute in the SuperType, each instance of the SuperType will have its own reference attribute, but the SubType inherits the SuperType using the prototype chain. At this time, the prototype of the SubType is an instance of the SuperType. At this time, create multiple instances of the SubType, and these instances will share only one reference attribute, Therefore, as long as the value in the reference attribute is changed in one instance, the value in other instances will change.
  2. When creating an instance of a subtype, you cannot pass parameters to the constructor of a supertype.

Borrow constructor

Call the constructor of the supertype inside the subclass constructor.

function SuperType(){
	this.colors = ['red', 'blue', 'green'];
}

function SubType(){
	SuperType.call(this);
}
		
var instance1 = new SubType();
instance1.colors.push('black');
console.log(instance1.colors);
		
var instance2 = new SubType();  // ['red', 'blue', 'green', 'black']
console.log(instance2.colors);  // ['red', 'blue', 'green']

Combinatorial inheritance

Composite inheritance, sometimes called pseudo classical inheritance, refers to an inheritance mode that combines the prototype chain and the technology of borrowing constructor together, so as to give full play to the advantages of the two.

function SuperType(name){
	this.name = name;
	this.colors = ['red', 'blue', 'green'];
}
		
SuperType.prototype.sayName = function() {
	console.log(this.name);
}
		
function SubType(name, age){
	SuperType.call(this, name);
	this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
	console.log(this.age);
}
		
		
var instance1 = new SubType('Nicholas', 29);
instance1.colors.push('black');
console.log(instance1.colors);  // ['red', 'blue', 'green', 'black']
instance1.sayName();  // 'Nicholas'
instance1.sayAge();  // 29
		
var instance2 = new SubType('Greg', 27);
console.log(instance2.colors);  // ['red', 'blue', 'green']
instance2.sayName();  // 'Greg'
instance2.sayAge();  // 27

Disadvantages: in any case, the supertype constructor is called twice.

Prototype inheritance

Prototype inheritance is normalized using Object.create(). This method receives two parameters:

  1. An object used as a prototype for a new object
  2. An object that defines additional properties for the new object.
var person = {
	name: 'Nicholas',
	friends: ['Shelby', 'Court', 'Van']
}
var anotherPerson = Object.create(person, {
	name: {
		value: 'Greg'
	}
});
console.log(anotherPerson.name)  // 'Greg'

Parasitic inheritance

Parasitic inheritance is to create a function that is only used to encapsulate the inheritance process. The function internally enhances the object in some way, and finally returns the object as if it really did all the work.

function createAnother(origin) {
	var clone = object(origin);
	clone.sayHi = function(){
		console.log('Hi');
	}
	return clone;
}

var person = {
	name: 'Nicholas',
	friends: ['Shelby', 'Court', 'Van']
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); // 'Hi'

The object function used is not necessary. Any function that can return a new object is applicable to this mode.

Parasitic combinatorial inheritance

The so-called parasitic combinatorial inheritance is to inherit attributes by borrowing constructors and methods by mixing prototype chains.

function inheritPrototype(subType, superType) {
	var prototype = object(superType.prototype);
	prototype.constructor = subType;
	subType.prototype = prototype;
}

function SuperType(name) {
	this.name = name;
	this.colors = ['red', 'blue', 'green'];
}

SuperType.prototype.sayName = function() {
	console.log(this.name);
}

function SubType(name, age) {
	SuperType.call(this, name);
	this.age = age;
}

inheritPrototype(SubType, SuperType);

The efficiency of this example is that it only calls the SuperType constructor once, and therefore avoids creating unnecessary and redundant attributes on SubType.prototype. At the same time, the prototype chain can remain unchanged.

closure

  • Closures are functions that can read internal variables of other functions

  • Usage: create another function inside one function

  • There are two greatest uses: reading the variable values of other functions and keeping these variables in memory all the time

  • Disadvantages: it will cause memory leakage (the reference cannot be destroyed and always exists)

Event, event flow

Event capture

Less specific nodes should receive events earlier, while the most specific nodes should receive events last.

Event Bubbling

The event flow of IE is called event bubbling, that is, the event is received by the most specific element at the beginning, and then propagated up to the less specific node level by level.

DOM2 level event flow

Three stages:

  1. Event capture phase
  2. At target stage
  3. Event bubbling phase

js event loop mechanism

Garbage collection mechanism

Marking algorithm

Approximate process

  • The garbage collector adds a flag to all variables in memory at run time
  • Start traversing from the root node of each object and change the non garbage node to 1
  • Clean up all garbage marked 0, destroy and recycle the memory space occupied by them
  • Finally, mark all objects in memory as 0 and wait for the next round of recycling

advantage

The implementation is simple. Marking is only divided into playing and not playing, so it can be marked with one binary

shortcoming

After clearing, the memory location of the remaining objects will not change, resulting in discontinuous free memory space and memory fragmentation.

In order to find the appropriate memory block, three allocation strategies can be adopted

  • First fit, find a block greater than or equal to size and return immediately
  • Best fit, traverse the entire free list and return the smallest block greater than or equal to size
  • Worst fit, traverse the entire free list, find the largest block, then cut it into two parts, one size, and return the part

To sum up, the mark removal algorithm has two obvious disadvantages:

  • Memory fragmentation: the free memory is discontinuous, which is prone to many free memory blocks, and the allocated memory may be too large to find a suitable block.
  • Slow allocation speed: even if the first fit policy is used, its operation is still an O(n) operation.

Label sorting algorithm

At the end of the tag, the living object will be moved to a section of memory, and finally the boundary memory will be cleaned up

Reference counting algorithm

Its strategy is to track how many times each value is used

  • When a variable is declared and a value of a reference type is assigned to the variable, the number of references to the value is 1
  • If the same value is assigned to another variable, the number of references to the value is increased by 1
  • When the value of the variable is overwritten by other values, the number of references to the overwritten value is reduced by 1
  • When the number of references of this value is 0, it indicates that there are no variables in use, and the space is recycled.

advantage

  • The reference count is recycled when the number of references of the value is 0, so it can recycle garbage immediately
  • The mark clearing algorithm needs to be performed every other period of time, and each time it needs to pause the GC of the main thread for a period of time. In addition, the mark clearing algorithm needs to traverse the active and inactive objects in the heap to clear, while the reference count only needs to be counted during reference.

shortcoming

  • The reference counting algorithm needs a counter, which takes up a lot of space, because the upper limit of the number of references is not known
  • Unable to resolve the memory recycling problem caused by circular reference

V8 optimization of GC

Generational garbage collection

New and old generation

  • Cenozoic: it has a short survival time and usually supports a capacity of 1~8M
  • Old generation: the survival time is long and the capacity is usually large

New generation waste recycling

Garbage collection is carried out through a short hair called Scavenge. In this algorithm, a Cheney algorithm is mainly used.

Cheney algorithm divides heap memory into two parts, free area and used area

The newly added objects will be stored in the usage area. When the usage area is full, a garbage cleaning operation will be performed.

During garbage collection, the active objects in the usage area will be marked, then the marked active objects will be copied to the free area, then the usage area will be cleared, and finally the roles will be exchanged, that is, the original usage area will become a free area, and the original free area will become a usage area.

When an object still survives after multiple garbage cleaning, it will be considered as an object with a long life cycle, and then it will be moved to the old generation for recycling by using the old generation recycling strategy.

In another case, if an object is copied to the free area and the space occupied by the free area exceeds 25%, the object will be directly promoted to the space of older generations. The reason is that if the proportion is too large, it will affect the subsequent memory allocation.

Old generation garbage collection

The objects in the old generation are usually large. If they are copied like the objects in the new generation, it will be very time-consuming, resulting in low recovery execution efficiency. Therefore, the old generation recycler directly adopts the mark removal algorithm mentioned above.

Parallel recycling

Because js is a single threaded language running on the main thread, the execution of js script will be blocked during garbage collection. You need to wait for the garbage collection to resume the execution of the script. This behavior is called full pause.

If the garbage collection time is too long, it may cause problems such as page jam. Therefore, the V8 team introduced a parallel recycling mechanism.

The so-called parallelism means simultaneous. It means that when the garbage collector runs on the main thread, it starts multiple auxiliary threads and performs the same recycling work at the same time.

Incremental marking and lazy cleanup

Although the introduction of parallel recycling strategy improves the garbage collection efficiency, it is still a full pause recycling method. For the older generation, it stores some large objects. For these large objects, even if the parallel strategy is used, it will still consume a lot of time.

Therefore, in 2011, V8 optimized the tagging of the older generation, switching from full pause to incremental tagging.

What is increment?

Increment is to divide a GC into many small steps, and let the application logic execute for a while after each small step is executed. In this way, a GC is completed after alternating for many times.

But after each small step is completed, how to pause to execute the application, and then how to resume? What if the application changes the marked reference relationship again?

In order to solve these two problems, V8 adopts three-color marking and write barrier

Trichromatic marking

The three color marking method uses two marking bits and a marking worksheet for each object. The two marking bits encode three colors: white, gray and black

  • White refers to objects that are not marked themselves
  • Gray means that it is marked, and the member variable (the reference object of the object) is not marked
  • Black means that both itself and member variables are marked

At first, all objects are white. Starting from the root node, the root node is marked as gray and pushed into the marking worksheet. When the collector pops up an object from the marking worksheet and accesses the reference object of the object, it will change from gray to black. At the same time, the reference object will be turned into gray and added to the marking worksheet.

Go down until there are no gray objects to mark, that is, there are no reachable (no referenced) objects, and all the remaining white objects are unreachable, that is, waiting for recycling

My summary: My Summary
reference material

"Hard core JS" do you really understand the garbage collection mechanism

Tags: Javascript

Posted on Sun, 19 Sep 2021 03:47:41 -0400 by Vasudhevan