The Latest and Hottest 20 Interview Questions in JavaScript
This article collects and sorts out some js hot interview questions and answers that are common in the process of my own interview and listening to other people's interviews. I hope it will be helpful to you.
1. JavaScript Garbage Collection Mechanism
This question starts with the type of the variable. If it is a variable of value type, it is directly stored in the call stack. When the call stack pops up, the memory occupied by the variable is recovered. If it is a reference type, the pointer to the heap is stored in the call stack. When the call stack pops up, the stack space will be emptied and recycled, and the space occupied by the heap needs to use the garbage collection mechanism.
The memory in the heap is divided into two areas: the new generation and the old generation. The new generation stores newly added objects and uses secondary garbage collector; the old generation stores long-lived objects and uses the main Garbage collector. The recycling mechanism of the collector is to mark active objects and inactive objects, and first reclaim the memory of inactive objects after the marking is completed.
Secondary garbage collector (new generation): using the scavenge algorithm, it is divided into object area and free area. When the object area is almost full, it will perform a garbage cleaning operation to clear the inactive objects, and then remove the active objects. The whole object is copied to the free area in an orderly manner, and the operation of the whole memory is also completed. After the copy is completed, the roles of the two areas are reversed, the target area becomes the free area, and the free area becomes the target area. If an object undergoes two rollovers and is still in stock it is moved to the stale space.
Main garbage collector: The main garbage collector adopts the mark-clear algorithm for garbage collection (reference counting is not a mainstream recycling mechanism). The marking phase is to traverse the call stack. The objects that can be accessed are active objects. The result is that the junk data will be cleared,
Disadvantages of the mark-and-sweep method:
A large number of discontinuous memory fragments will be generated. Too much fragmentation will cause large objects to be unable to allocate enough contiguous memory, so another algorithm - mark-collation method
this mark process is still the same as in the mark-clear algorithm, but the subsequent steps are not Clean up recyclable objects directly, but let all surviving objects move to one end, and then directly clean up the memory outside the end boundary. You can refer to the picture below:
Timing of garbage collection:
full pause
Now you know that V8 uses the secondary garbage collector and the main garbage collector to handle garbage collection. However, since JavaScript runs on the main thread, once the garbage collection algorithm is executed, the JavaScript script that is being executed needs to be paused. Resume script execution after garbage collection is complete. We call this behavior Stop-The-World
Full pause This will cause the page to freeze.
Incremental Marking Algorithm
Using the incremental marking algorithm, a complete garbage collection task can be divided into many small tasks. The execution time of these small tasks is relatively short and can be interspersed with other JavaScript tasks. In this way, when the above animation effects are executed, there will be no It will make users feel that the page is stuck due to garbage collection tasks
There is also a new thread for garbage collection, which will not cause lag at all
2.White screen
White screen time refers to the time when the browser starts displaying content. Therefore, we only need to know the time point when the browser starts to display the content, that is, the time point when the page white screen ends to obtain the white screen time of the page.
Therefore, the white screen time can be calculated as follows:
-
When the Performance API is available
White screen time = firstPaint - performance.timing.navigationstart
-
When the Performance API cannot be used
White screen time = firstPaint - pageStartTime
If the white screen time is too long, it will affect the user experience. In order to shorten the white screen time, the following strategies can be used:
- Remove these two types of file downloads through inline JavaScript and inline CSS, so that the rendering process can start directly after getting the HTML file
- Not all occasions are suitable for inlining, so you can also reduce the file size as much as possible, such as removing some unnecessary comments through tools such as webpack, and compressing JavaScript files.
- sync or defer some JavaScript tags that do not need to be used in the parsing HTML stage
- For large CSS files, you can use media query properties to split them into multiple CSS files for different purposes, so that specific CSS files will only be loaded in specific scenarios.
The first screen time refers to the time from when the user opens the website to when the content rendering of the first screen of the browser is completed Usually the methods for calculating the first screen are:
- First screen module labeling method
- Count the time of the slowest image loaded on the first screen
3. Generate 10000 li tags
(1) The most common method is to manipulate DOM elements and insert them directly:
<script>
var container = document.getelementById('container")
for(let i = e; 1 < 10000; i++){
let li = document.createElement("li');
li.innerHTML="hello world"
container.appendChild(li);
}
</script>
The efficiency of using this method will be very low, and even the phenomenon of splash screen and stuck screen will appear on the page. Because every time the appendChild()
method is called, the browser will restain the page. If a large number of DOM nodes are updated, it will consume a lot of performance and affect the user experience.
(2) Use Fragment document fragments:
<script>
var container. documentgetElementById('container")
var fragment. document. createDocumentFragment()
for(let 1 = 0; i < 10000; i++){
let li = document. createElement('li');
li.innerHTML = "hello world"
fragment.appendChild(li)
}
container.appendchild(fragment);
</script>
JavaScript provides a document fragment DocumentFragment mechanism. Put all the nodes to be constructed in the document fragment for execution, so that the document tree will not be affected, and the page will not be rendered. After the nodes are all constructed, add the document fragment object to the page. At this time, all the nodes will be rendered at one time, which can reduce the burden on the browser and improve the page rendering speed
4.How to judge the completion of DOM loading
readyState
document.readyState
returns the state of the current document, the properties are as follows:
- uninitialized: has not started loading
- loading: loading
- interactive: has been loaded, the document and the user can start interacting
- complete: Loading is complete
onload
When the onload event is triggered, all DOM, style sheets, scripts, images, and flash on the page have been loaded
-
onload event
All browsers support the onload event, so we don't need to be compatible, just callwindow.onload = funetion(){ }
-
DOMContentLoaded event
Different browsers support DOMContentLoaded differently, so we need to be compatible with different browsers when implementing itWhen the DOMContentLoaded event is triggered, only when the DOM is loaded, excluding style sheets, images, and flash
5.performance optimization
Performance optimization is a big test point, see the details:
Front-end performance optimization - summary of optimization methods and auxiliary tools
6. JavaScript data types
There are eight data types in JavaScript, which are Undefined, Null, Boolean, Number, String, Object, Symbol, and BigInt. Among them, Symbol and BigInt are new data types in ES6: BigInt is a digital type of data, which can represent Integers in arbitrary precision format, use BigInt to safely store and manipulate large integers
7.Closure
Closures allow you to access the scope of an outer function from within an inner function
In JavaScript, according to the rules of lexical scope, internal functions can always access the variables declared in their external functions. When an internal function is returned by calling an external function, even if the external function has been executed, the internal function reference The variables of the outer function are still stored in memory, and we call the collection of these variables a closure. The JavaScript language's scope chain is determined by lexical scope, and lexical scope is determined by code structure.
Advantages of closures:
internal functions can access local variables of external functions, expanding the scope of variables
Disadvantages of closures: Variables will reside in memory, causing memory loss problems
Solution: Set the closure function to the disadvantage of nu11 closure
Closure case:
var lis = document. getElementsByTagName('li');
for(var i=0;i<lis.length;i++){
(function(i){
lis[i].onclick = function(){
alert(i);
}
})(i)
}
8. Scope
-
Global scope:
Objects that can be accessed anywhere in the code have a global scope. Generally, there are three situations for having a global scope:- The outermost function and variables defined outside the outermost function
- all variables that are not directly assigned
- properties of all window objects Such as scrollTop, screenX, etc.
-
Function scope:
Function scope refers to the variables declared inside the function, which is exactly the opposite of the global scope. Inner scopes can access outer scopes, but outer scopes cannot access inner scopes -
Block-level scope:
Block-level scope can be declared through let and const. The declared variable cannot be accessed outside the specified block-level scope. Block-level scope variables will not be promoted and cannot be declared repeatedly
Definition and Formation of Scope Chain When the required variable cannot be found in the scope where it is located, it will search up layer by layer until it finds the global scope and has not found it, it will give up the search. This layer-by-layer relationship is the scope chain.
9. The difference between modular CommonJS and ES Module
They have three major differences:
- CommonJS modules output a copy of a value, that is, once a value is output, changes within the module will not affect the value; ES6 modules output a reference to a value
- CommonJs modules are loaded at runtime, and ES6 modules are compiled-time output interfaces
- The require() of the CommonJS module loads the module synchronously, and the import command of the ES6 module loads asynchronously, and there is an independent parsing phase of module dependencies
Runtime loading:
CommonJS modules are objects; that is, when inputting, the entire module is loaded first, an object is generated, and then the method is read from the object. This loading is called "runtime loading"
Loading at compile time:
ES6 modules are not objects, but explicitly specify the output code through the export command, and the import takes the form of a static command. That is, when importing, you can specify to load a certain output value instead of loading the entire module. This loading is called "compile-time loading"
note:The CommonJS specification is generally not used in browsers
The parsing process of ES Module can be divided into three stages:
Phase 1: Construction, find js files according to the address, download them, and parse them into module records ( Module Record );
Phase 2: Instantiation, instantiate the module record, allocate memory space, parse the import and export statements of the module, and point the module to the corresponding memory address
Phase 3: Evaluation , run the code, calculate the value, and fill the value into the memory address
10. Why is Js single-threaded
JavaScript's single thread is related to its use.
As a browser scripting language, the main purpose of JavaScript is to interact with users and manipulate the DOM. This determines that it can only be single-threaded, otherwise it will bring very complicated synchronization problems. For example, suppose JavaScript has two threads at the same time, one thread adds content to a certain DOM node, and the other thread deletes this node. Which thread should the browser take as the basis? Therefore, in order to avoid complexity, JavaScript has been single-threaded since its inception, which has become the core feature of this language and will not change in the future.
shortcoming:
Single-threading brings problems: all tasks need to be queued, and the next task will only be executed after the previous task is completed. If the previous task takes a long time, the latter task will have to wait forever.
Solution:
All tasks can be divided into two types, one is a synchronous task, and the other is an asynchronous task. A synchronous task refers to a task that is queued for execution on the main thread. Only when the previous task is executed can the next task be executed. Asynchronous task refers to a task that does not enter the main thread but enters the "task queue". Only the "task The queue "notifies the main thread that an asynchronous task can be executed, and the task will enter the main thread for execution.
11. '==' conversion rules
- If one value is null and the other is undefined, they are equal
- If one value is a number and the other is a string, first convert the string to a number, then use the converted value for comparison.
- If one of the values is true, convert it to 1 before comparing. If one of the values is false, convert it to 0 before comparing.
- If one value is an object and the other is a number or string, convert the object to a primitive value before comparing.
- None of the other types compare equal.
12. ['1' , '2' , '3'].map(parseInt) what & why
When I first saw this question, the answer that popped up in my mind was [1,2,3], but the real answer is [1,NaN,NaN]
-
First let's review the first parameter callback of the map function:
var new_array arr. map(function callback(currentValue[, index[, array]]) {//Return element for new array }[, thisarg])
This callback can receive a total of three parameters, where the first parameter represents the element currently being processed, and the second parameter represents the index of the element.
- and parselnt is used to parse the string, making the string an integer of the specified radix
parseint(string, radix)
Receives two parameters, the first represents the value (string) to be processed, and the second represents the base when parsing - After understanding these two functions, we can simulate the operation
1.parselnt('1',0) //When the radix is 0, and the string parameter does not start with "0x" and "0", it will be processed according to 10. return 1 at this time
2.parselnt('2',1)//Among the numbers represented by base 1 (1 base), the maximum value is less than 2, so it cannot be parsed and NaN is returned
3.parselnt('3',2)//Among the numbers represented by base 2 (binary), the maximum value is less than 3, so it cannot be parsed and returns NaN The unary system is the numbers 1, 2, 3, 4, 5 expressed as 1, 11, 111, 1111, 11111 in unary
solve:
['1','2','3'].map(str=>parseInt(str));
['1','2','3'].map(Number);
13. Introduce the difference between Set, Map, WeakSet and WeakMap
Set:
- Members are unique, unordered and not duplicated
- [value,value], the key value is the same as the key name (or only the key value, no key name).
- It can be traversed, the methods are: add, delete, has
WeakSet:
- members are objects
- Members are all weak references, which can be recycled by the garbage collection mechanism and can be used to save DOM nodes, which is not easy to cause memory leaks
- Cannot traverse, methods include add, delete, has
Map:
- Essentially a collection of key-value pairs, similar to a collection
- It can be traversed, and there are many ways to convert with various data formats
WeakMaps:
- only accepts objects as keys (except null), and does not accept other types of values as keys
- The key name is a weak reference, the key value can be arbitrary, and the object pointed to by the key name can be garbage collected
- Cannot be traversed, methods include get, set, has, delete
14. object traversal method
(1) for...in
for...in loops through the object's own and inherited (on the prototype chain) enumerable properties (excluding Symbol properties)
(2) Object.keys(obj)
Object.keys returns an array, including all enumerable properties (excluding Symbol properties) of the object itself (excluding inherited ones)
The effect of Object.keys is the same as that of for in+hasOwnProperty
(3) Object. getOwnPropertyNames(obj)
Object.getOwnPropertyNames returns an array containing all properties of the object itself (excluding Symbol properties, but including non-enumerable properties)
(4) Object. getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols returns an array containing all the Symbol properties of the object itself
(5) Reflect.ownKeys(obj)
Reflect.ownKeys returns an array containing all properties of the object itself, no matter whether the property name is Symbol or string, and whether it is enumerable or not.
15. What is the difference between an arrow function and a normal function
- The question pointed to by this:
The this in the arrow function is only determined when the arrow function is defined, and it cannot be modified (call, apply, bind)
The this of the arrow function points to the this of the first ordinary function in the outer layer when it is defined -
Arrow functions are anonymous functions, cannot be used as constructors, and cannot use
-
Arrow functions cannot bind arguments, use remaining parameters (...) to resolve
- Arrow functions have no prototypee
- Arrow functions are more concise than ordinary functions
16. Talk about the front-end login process
When logging in for the first time, the front end adjusts the login interface of the back end, sends the user name and password, the back end receives the request, verifies the user name and password, and if the verification is successful, it returns a token and a value of user information to the front end, and the front end gets the token, Store the token in vuex, and then store the value of the token in the browser Cookies from Vuex. Save the user information in vuex and then store it in LocalStroage, and then jump to the next page. According to the requirements of the back-end interface, the pages that cannot be accessed without logging in need to judge whether there are cookies in the front-end every time the page jumps. Token, jump to the login page if there is no token, and jump to the corresponding page if there is one. We should add token every time we send a post/get request. The common method is to add a global interceptor to the project utils/service.js. Put the token value into the request header. The backend judges whether there is a token in the request header. If there is a token, it will get the token and verify whether the token has expired. Here, an invalid token will be returned when it expires, and then jump back to the login page to log in again and clear it. local user information
17. The realization principle of the difference between var, let and const
Variable life cycle: declaration (scope registers a variable), initialization (allocation of memory, initialized to undefined), assignment
- var: When encountering a scope with var, declaration and initialization have been completed before any statement is executed, which is why the variable is promoted and the value is undefined
- function: declaration, initialization, and assignment are all completed at the beginning, so the variable promotion priority of the function is higher
- let: The parser enters a block-level scope and finds the let keyword. The variable is just declared first, and it has not reached the step of initialization. At this time, if you access in advance before this scope, an error xx is not defined will be reported, which is the origin of the temporary dead zone. It will not enter the initialization phase until the line with let is parsed. If the line of let is an assignment operation, the initialization and assignment will be performed at the same time
- const and class are the same as let
18. The difference between null and undefined
- The meaning of undefined is undefined, and the meaning of null is an empty object.
- When a general variable is declared but not yet defined, it will return undefined, and null is mainly used to assign values to some variables that may return objects as initialization
- When using typeof to judge these two types, Null typing will return object, which is a historical problem.
- Returns true when a double equal sign is used to compare two types of values, and false when triple equal signs are used.
19. JavaScript event loop mechanism
- All synchronous tasks are executed sequentially on the main thread to form an execution stack (call stack), and asynchronous tasks are put into a task queue
- When the task in the execution stack is executed, check whether the microtask in the microtask queue is empty, and execute it if there is any. If another microtask is encountered during the execution of the microtask, it will be added to the end of the microtask queue to continue execution. Execute all microtasks
- After the microtask is executed, go to the task queue to check whether the macrotask is empty, and if there is, take out the macrotask that entered the queue first and push it into the execution stack to execute its synchronization code
- Then go back to step 2 to execute the microtasks in the macrotask, and repeat until the macrotask is also executed, and so on.
Microtasks: :
process.nextTick, MutationObserver, Promise.then, catch finally
Macro tasks:
I/O user interaction events (such as mouse clicks, page scrolling, zooming in and out, etc.), setTimeout, setlnterval, setlmmediate, requestAnimationFrame
20. What does the New operator do
- First create a new object
- Set the prototype, set the prototype of the object as the prototype object of the function
- Let the this of the function point to this object, execute the code of the constructor (add properties to this new object)
- Determine the return value type of the function. If it is a value type, return the created object. If it is a reference type, return an object of this reference type