Previous points here: ↓
Summary of JS interview questions (I)
Summary of JS interview questions (II)
Summary of JS interview questions (III)
31. JS single thread or multi thread, how to display asynchronous operation
Reference answer:
JS itself is single threaded. It relies on the browser to complete asynchronous operations.
Resolution:
Specific steps,
1. The main thread executes all the code in js.
2. When the main thread finds a task that needs to be asynchronous during execution, it throws it to the browser (the browser creates multiple threads for execution), and creates a corresponding callback function in the callback queue (the callback function is an object, including whether the function has been executed, etc.).
3. The main thread has executed all synchronization code. Start listening to callback queue. Once a thread task in the browser is completed, the state of the callback function will be changed. When the main thread sees that the status of a function is completed, it will execute the function.
32. Function map/forEach/reduce/filter of JavaScript array
Reference answer:
1. map
// map //Function: traverse the array //Return value: new array // Change: no var arr = [2, 5, 3, 4]; var ret = arr.map(function(value) { return value + 1; }); console.log(ret); //[3,6,4,5] console.log(arr); //[2,5,3,4]
2. forEach
// forEach method // Function: traverse each item of the array // Return value: undefined // Change: no var arr = [2, 5, 3, 4]; var ret = arr.forEach(function(value) { console.log(value); // 2, 5, 3, 4 }); console.log(ret); //undefined console.log(arr); //[2,5,3,4]
3. reduce
// reduce method // Function: iterate over the array, then operate in pairs, and finally return a value // Return value: the result of return // Change: no var arr = [1, 2, 3, 4]; var ret = arr.reduce(function(a, b) { return a * b; }); console.log(ret); // 24 console.log(arr); // [1, 2, 3, 4]
4. filter
// filter filtering // Role: filter some elements // Return value: a new array that meets the filter criteria // Whether to change the original array: no var arr = [2, 5, 3, 4]; var ret = arr.filter(function(value) { return value > 3; }); console.log(ret); //[5,4] console.log(arr); //[2,5,3,4]
33. JS block level scope and variable promotion
Reference answer:
1. Block level scope
Scopes in JS include: global scope and function scope. There is no concept of block scope. ECMAScript 6 (ES6 for short) adds a block level scope. The block scope consists of {}, and {} in the if statement and for statement also belongs to the block scope.
2. Variable lifting
- If a variable is declared in a function, the variable declaration is promoted to the beginning of the function
- If the variable declaration is a global variable, promote the variable declaration to the beginning of the global scope
Resolution:
< script type = "text/javascript" > { var a = 1; console.log(a); // 1 } console.log(a); // 1 // It can be seen that variables defined by var can be accessed across block scopes. (function A() { var b = 2; console.log(b); // 2 })(); // console.log(b); // report errors, // It can be seen that variables defined through var cannot be accessed across function scopes if (true) { var c = 3; } console.log(c); // 3 for (var i = 0; i < 4; i++) { var d = 5; }; console.log(i); // 4 (at the end of the cycle, i is already 4, so i here is 4) console.log(d); // 5 // Variables defined by var in if statement and for statement can be accessed from outside, // It can be seen that if statements and for statements belong to block scope, not function scope. { var a = 1; let b = 2; const c = 3; { console.log(a); // one The child scope can access the variables of the parent scope console.log(b); // two The child scope can access the variables of the parent scope console.log(c); // three The child scope can access the variables of the parent scope var aa = 11; let bb = 22; const cc = 33; } console.log(aa); // eleven // Variables scoped by subblocks can be accessed across blocks // console.log(bb); // report errors bb is not defined // console.log(cc); // report errors cc is not defined } < /script>
expand:
The difference between var, let and const
- Variables defined by var have no block concept and can be accessed across blocks, not functions.
- let defined variables can only be accessed within the block scope, not across blocks or functions.
- const is used to define constants. It must be initialized (that is, it must be assigned) when used. It can only be accessed in the block scope and cannot be modified.
- The same variable can only be declared in one way, otherwise an error will be reported
< script type = "text/javascript" > // Block scope { var a = 1; let b = 2; const c = 3; // c = 4; // report errors // let a = 'a'; // Error reporting note: Yes, above var a = 1; The line reported an error // var b = 'b'; // Error reporting: this bank reports an error // const a = 'a1'; // Error reporting note: Yes, above var a = 1; The line reported an error // let c = 'c'; // Error reporting: this bank reports an error var aa; let bb; // const cc; // report errors console.log(a); // 1 console.log(b); // 2 console.log(c); // 3 console.log(aa); // undefined console.log(bb); // undefined } console.log(a); // 1 // console.log(b); // report errors // console.log(c); // report errors // Function scope (function A() { var d = 5; let e = 6; const f = 7; console.log(d); // 5 console.log(e); // 6 (in the same {}, it also belongs to the same block and can be accessed normally) console.log(f); // 7 (in the same {}, it also belongs to the same block and can be accessed normally) })(); // console.log(d); // report errors // console.log(e); // report errors // console.log(f); // report errors < /script>
34. The difference between null and undefined
Reference answer:
Null: null type, representing "null value", representing a null object pointer. Use typeof operation to get "object", so you can think of it as a special object value.
Undefined: undefined type. When a declared variable is uninitialized, the result is undefined.
35. What JS operations will cause memory leakage
Reference answer:
1) Memory leak caused by unexpected global variables
function leak() { leak = "xxx"; //leak becomes a global variable and will not be recycled }
2) Memory leak caused by closure
function bindEvent() { var obj = document.createElement("XXX"); obj.οnclick = function() { //Even if it's a empty function }; }
Closures can maintain local variables in a function so that they cannot be released. When defining an event callback in the above example, closures are formed because the function is defined in the function and the reference of the internal function event callback is exposed.
The solution is to define the event handler function in the external function, release the closure, or delete the reference to dom in the external function that defines the event handler function.
//Define the event handler function externally function onclickHandler() { //do something } function bindEvent() { var obj = document.createElement("XXX"); obj.οnclick = onclickHandler; } //In the external function that defines the event handler function, remove the reference to the dom function bindEvent() { var obj = document.createElement("XXX"); obj.οnclick = function() { //Even if it's a empty function }; obj = null; }
3) No cleaned DOM element references
var elements = { button: document.getElementById("button"), image: document.getElementById("image"), text: document.getElementById("text") }; function doStuff() { image.src = "http://some.url/image"; button.click(): console.log(text.innerHTML) } function removeButton() { document.body.removeChild(document.getElementById('button')) }
4) Forgotten timer or callback
var someResouce = getData(); setInterval(function() { var node = document.getElementById("Node"); if (node) { node.innerHTML = JSON.stringify(someResouce); } }, 1000);
Such code is very common. If the element with id Node is removed from the DOM, the timer will still exist. At the same time, because the callback function contains a reference to someResource, the someResource outside the timer will not be released.
5) Memory leak caused by the presence of child elements
Yellow refers to being directly referenced by js variables. In memory, red refers to being indirectly referenced by js variables. As shown in the figure above, refB is indirectly referenced by refA, so that even if the refB variable is cleared, the child element refB will not be recycled. Due to the indirect reference of parentNode, as long as it is not deleted, all its parent elements (the red part in the figure) will not be deleted.
6) IE7/8 reference counting problems caused by using circular references
function fn() { var a = {}; var b = {}; a.pro = b; b.pro = a; } fn();
After fn() is executed, both objects have left the environment. There is no problem in the mark clearing mode. However, under the reference counting strategy, because the number of references of a and b is not 0, the memory will not be recycled by the garbage collector. If FN function is called in a large number, it will cause memory leakage. On IE7 and IE8, the memory rises sharply.
Some objects in IE are not native js objects. For example, the objects in DOM and BOM are implemented in the form of COM objects in C + +, and the garbage collection mechanism of COM objects adopts the reference counting policy. Therefore, even if the js engine of IE adopts the tag elimination policy, the COM objects accessed by js are still based on the reference counting policy In other words, as long as COM objects are involved in ie, there will be the problem of circular reference.
var element = document.getElementById("some_element"); var myObject = new Object(); myObject.e = element; element.o = myObject;
The above example is based on a DOM element and a native js object A circular reference is created between (myObject). The variable myObject has an attribute named e pointing to the element object, and the variable element also has an attribute named o pointing back to myObject. Due to this circular reference, even if the DOM in the example is removed from the page, it will never be recycled.
Looking at the above example, some people will feel too weak. Who would do such boring things, but in fact, we often do so
window.οnlοad = function outerFunction() { var obj = document.getElementById("element"): obj.οnclick = function innerFunction() {}; };
This code looks ok, but obj refers to document. getElementById("element"), and the onclick method of document. getElementById("element") will refer to variables in the external environment, including obj. Isn't it very hidden.
The simplest solution is to manually remove the circular reference, such as the function just now
myObject.element = null; element.o = null; window.οnlοad = function outerFunction() { var obj = document.getElementById("element"): obj.οnclick = function innerFunction() {}; obj = null; };
Setting a variable to null means cutting off the connection between the variable and the value it previously referenced. When the garbage collector runs next time, it will delete these values and reclaim the memory they occupy. It should be noted that there is no circular reference in IE9 + that leads to Dom memory leakage. It may be that Microsoft has optimized it, or the collection method of Dom has changed
Resolution:
1. JS recycling mechanism
The mechanism of JavaScript garbage collection is very simple: find out the variables that are no longer used, and then release the memory occupied by them. However, this process is not real-time. Because of its high overhead, the garbage collection system (GC) will execute periodically at fixed time intervals.
Which variable is useless? Therefore, the garbage collector must track which variable is useless, and mark the variables that are no longer useful for future memory recovery. The strategies for marking useless variables may vary depending on the implementation. Usually, there are two implementation methods: Mark clearing and reference counting. Reference counting is not very common, and mark clearing is more difficult Is commonly used.
2. mark and sweep
The most common garbage collection method in js is mark clearing. When a variable enters the environment, for example, if a variable is declared in a function, the variable is marked as "entering the environment" . logically, the memory occupied by variables entering the environment can never be released, because they may be used as long as the execution flow enters the corresponding environment. When variables leave the environment, they are marked as "leaving the environment".
function test() { var a = 10; //Marked to enter the environment var b = 20; //Marked to enter the environment } test(); //After execution, a and b are marked to leave the environment and recycled
3. Reference counting
The meaning of reference count is to track and record the number of times each value is referenced. When a variable is declared and a reference type value (function object array) is added When assigned to this variable, the number of references to this value is 1. If the same value is assigned to another variable, the number of references to this value is increased by 1. On the contrary, if the variable containing the reference to this value obtains another value, the number of references to this value is reduced by 1. When the number of references to this value becomes 0, it indicates that there is no way to access this value again, so it is difficult It can reclaim the memory space occupied by it. In this way, when the garbage collector runs next time, it will free the memory occupied by values with reference times of 0.
function test() { var a = {}; //The number of references of a is 0 var b = a; //The number of citations of a plus 1 is 1 var c = a; //The number of citations of a plus 1 is 2 var b = {}; //The number of citations of a is reduced by 1 to 1 }
4. How to analyze memory usage
Google Chrome browser provides a very powerful JS debugging tool. The Memory view and profiles view allows you to take snapshots of the Memory when JavaScript code is running and compare these Memory snapshots. It also allows you to record the Memory allocation over a period of time. Different types of lists can be displayed in each result view, but it is most useful to us Useful are the summary list and the comparison list. The summary view provides different types of allocation objects and their total size: share size (the sum of all objects of a specific type) and retained size (share size plus the size of other objects that retain this object). distance shows how the object reaches the GC root (moderator's note: the Memory initially referenced can be searched for the term). The comparison view provides the same information, but allows you to compare different snapshots. This is very helpful to find leaks.
5. How to avoid memory leakage
1) Reduce unnecessary global variables or objects with long life cycle, and garbage collect useless data in time;
2) Pay attention to program logic and avoid "dead cycle";
3) Avoid creating too many objects. The principle is to return the unused items in time.
36. What is the difference between rearrangement and redrawing?
Reference answer:
1. Briefly describe the concept of rearrangement
After downloading all the components (HTML, JavaScript, CSS and pictures) in the page, the browser will parse and generate two internal data structures (DOM tree and rendering tree). The DOM tree represents the page structure and the rendering tree represents how DOM nodes are displayed. Rearrangement is the change of the geometric attributes of DOM elements, the structure of DOM tree changes, and the rendering tree needs to be recalculated.
2. Briefly describe the concept of redrawing
Redrawing is the browser behavior triggered by the change of the appearance of an element, such as changing the visibility, outline, background color and other attributes. The browser will redraw the element according to the new attributes of the element to make the element present a new appearance. Due to the flow layout of the browser, the calculation of the rendering tree usually only needs to be traversed once. Except for table and its internal elements, it may need to It takes several calculations to determine the attribute value of the node in the rendering tree, which takes twice as long as the same element. This is one of the reasons why we try to avoid using table to layout the page.
3. Briefly describe the relationship between redrawing and rearrangement
Redrawing will not cause rearrangement, but rearrangement will certainly cause redrawing. The rearrangement of an element usually brings a series of reactions, and even triggers the rearrangement and redrawing of the whole document. The performance cost is high.
4. Under what circumstances will rearrangement be triggered?
- When page rendering is initialized; (this cannot be avoided)
- Change the size of the browser window;
- When the element size changes;
- When the element position changes;
- When the element content changes;
- When adding or removing visible DOM elements.
5. There are five methods for rearrangement optimization
- Combine multiple operations that change style attributes into one operation to reduce DOM access.
- If you want to add DOM in batch, you can first separate the elements from the document flow, and then bring them into the document flow after the operation. This will only trigger a rearrangement. (Application of fragment element)
- Set the position attribute of the element that needs to be rearranged multiple times to absolute or fixed, so that this element is separated from the document flow, and its changes will not affect other elements. For example, elements with animation effects are best set to absolute positioning.
- Since the element whose display attribute is none is not in the rendering tree, the operation on the hidden element will not cause the rearrangement of other elements. If you want to perform complex operations on an element, you can hide it first and display it after the operation is completed. This triggers only two rearrangements when hidden and displayed.
- Operate the node multiple times in memory, and then add it to the document. For example, to get table data asynchronously, render to the page. You can get the data first, then build the html fragment of the whole table in memory, and then add it to the document at one time, rather than adding each row in a loop.
37. Publish subscribe design pattern
Reference answer:
Publish subscribe mode is also called observer mode. It defines a one to many dependency between objects. When the state of an object changes, all objects that depend on it will be notified. In JavaScript development, we generally use the event model to replace the traditional publish subscribe model.
Resolution:
Composition of publish subscribe mode
The most common publish / subscribe mode is our DOM event. Recall that we need to give a button and bind an event. When I click the button, I want to change its color and pop up a pop-up box on the page
Let's analyze the process: first, we need to know which button is bound to the event, and then we need to know what to do after triggering the event?
So who is the publisher?
It is a button in the DOM, because it is bound with an event. When we click the button, it releases the message to the subscriber
So who is the subscriber?
It is a click event. When a button is clicked, the dom publishes a message, and the event subscribes to it, so when it is clicked, the subscriber will receive the message
Simple example
When I was in college, a wanted to play games. I wasn't going to go to class in the afternoon. Then a told B that if the teacher asked me where I went in the afternoon, you would send me a message. Then, as expected, the teacher came in the afternoon and asked where Jia had gone? Then B sends a message to A. what does a do after receiving the message? B doesn't know. B is only responsible for sending a text message to a if the teacher asks.
38. What are the advantages and disadvantages of jsonp?
Reference answer:
Advantages and disadvantages of jsonp
-
- advantage
- 1.1 unlike the Ajax request implemented by the XMLHttpRequest object, it is limited by the same origin policy, and JSONP can cross the same origin policy;
- 1.2 it has better compatibility and can run in older browsers without the support of XMLHttpRequest or ActiveX
- 1.3 after the request is completed, the result can be returned by calling callback. Gave the caller permission for the callback method. This is equivalent to finally separating the controller layer from the view layer. The jsonp service I provide only provides pure service data. As for the page rendering and subsequent view operations after the service is provided, it is good for the caller to define them. If two pages need to render the same data, you only need to have different rendering logic. Both logic can use the same jsonp service.
-
- shortcoming
- 2.1 it only supports GET requests and does not support other types of HTTP requests such as POST
- 2.2 it only supports cross domain HTTP requests, which can not solve the problem of how to call JavaScript between two pages in different domains.
- 2.3 jsonp will not return various HTTP status codes when the call fails.
- 2.4 the disadvantage is security. In case of page injection vulnerability in the service providing jsonp, that is, the content of javascript returned by it is controlled by someone. So what's the result? All websites that call this jsonp will have vulnerabilities. So we can't control the danger under a domain name... So when using jsonp, we must ensure that the jsonp services used must be safe and trusted
39. Event binding compatible with various browser versions
Reference answer:
/* Compatible with low version IE, ele is the element that needs to bind events, eventName Is the event name (keep the addEventListener syntax, remove on), and fun is the event response function */ function addEvent(ele, eventName, fun) { if (ele.addEventListener) { ele.addEventListener(eventName, fun, false); } else { ele.attachEvent("on" + eventNme, fun); } }
40. What pits have typescript encountered
Reference answer:
main.ts reports an error (Cannot find module '. / App.vue'.)
Cause: typescript does not recognize the. vue file
terms of settlement:
Introduce the typescript declare Library of vue