Advanced front-end two-sided interview questions

If a constructor bind s an object, will the instance created by this constructor inherit the properties of the object? Why?

No inheritance, because according to the four rules of this binding, the priority of the new binding is higher than the bind display binding. When a Constructor call is made through new, a new object is created, which replaces the bind's object binding as this of this function and returns the new object without returning the object

Usage scenarios for TCP and UDP

  • TCP application scenarios: Scenarios with relatively low efficiency requirements but relatively high accuracy requirements. Because operations such as data confirmation, retransmission, and sorting are required during transmission, the efficiency is not as high as that of UDP. For example: file transfer (high accuracy and high requirements, but the speed can be relatively slow), receiving mail, remote login.
  • UDP application scenarios: Scenarios with relatively high requirements for efficiency and low requirements for accuracy. For example: QQ chat, online video, VoIP (instant messaging, high speed requirements, but occasional interruption is not a big problem, and the retransmission mechanism cannot be used here at all), broadcast communication (broadcast, multicast).

Difference between POST and PUT request

  • The PUT request is to send data to the server to modify the content of the data, but it does not increase the type of data, etc., that is to say, no matter how many times the PUT operation is performed, the result is not different. (It can be understood that the data is updated from time to time)
  • The POST request is to send data to the server. The request will change the type of data and other resources, and it will create new content. (It can be understood as creating data)

Application scenarios of closures

  • Curry bind
  • module

What does the New operator do?

1,First a new object is created
2,Set the prototype, set the prototype of the object to the function's prototype prototype object
3,let the function this Point to this object, execute the code of the constructor (add properties to this new object)
4,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 the object of this reference type

code output

const async1 = async () => {
  setTimeout(() => {
  }, 2000)
  await new Promise(resolve => {
  console.log('async1 end')
  return 'async1 success'
console.log('script start');
async1().then(res => console.log(res));
console.log('script end');
  .then(res => console.log(res))
setTimeout(() => {
}, 1000)

The output is as follows:

script start
script end

The execution of the code is as follows:

  1. First execute the synchronous belt, print out script start;
  2. When the timer timer1 is encountered, it will be added to the macro task queue;
  3. After that, Promise is executed, and promise1 is printed. Since Promise has no return value, the following code will not be executed;
  4. Then execute the synchronous code and print out the script end;
  5. Continue to execute the following Promise, .then and .catch expect the parameter to be a function, here is a number, so value penetration will occur, pass the value of resolve(1) to the last then, and print 1 directly;
  6. When encountering the second timer, add it to the micro-task queue, execute the micro-task queue, and execute the two timers in sequence. However, due to the timer time, timer2 will be printed out after two seconds, and the timer2 will be printed out after four seconds. Print out timer1 after seconds.

Understanding of WebSocket

WebSocket is a network technology provided by HTML5 for full-duplex communication between browsers and servers, and belongs to the application layer protocol. It is based on the TCP transport protocol and multiplexes the HTTP handshake channel. The browser and the server only need to complete one handshake, and a persistent connection can be created directly between the two, and two-way data transmission can be performed.

The emergence of WebSocket solves the drawbacks of half-duplex communication. Its biggest feature is that the server can actively push messages to the client, and the client can also actively push messages to the server.

WebSocket Principle: The client notifies the WebSocket server of an event with all recipients IDs. The server notifies all active clients immediately after receiving, only the ID in the server will handle this event.

The features of WebSocket are as follows:

  • Support two-way communication, more real-time
  • Can send text or binary data''
  • Based on the TCP protocol, the implementation of the server is relatively easy
  • The data format is relatively lightweight, the performance overhead is small, and the communication is efficient
  • No same-origin restrictions, clients can communicate with any server
  • The protocol identifier is ws (or wss if encrypted) and the server URL is the URL
  • It has good compatibility with HTTP protocol. The default ports are also 80 and 443, and the HTTP protocol is used in the handshake phase, so it is not easy to shield during the handshake, and can pass through various HTTP proxy servers.

The usage of Websocket is as follows: ​

In the client:

// Write WebSocket directly in index.html and set the port number of the server to 9999
let ws = new WebSocket('ws://localhost:9999');
// Triggered after the client establishes a connection with the server
ws.onopen = function() {
    console.log("Connection open."); 
// Triggered when the server sends a message to the client
ws.onmessage = function(res) {
    console.log(res);       // What is printed is the MessageEvent object
    console.log(;  // The received message is printed
// Triggered after the client and server have established a shutdown
ws.onclose = function(evt) {
  console.log("Connection closed.");

Implement template string parsing

Description: Implement the function to replace the variables inside {{}} in the template string.

Core: Use the string replacement method str.replace(regexp|substr, newSubStr|function) to replace strings with regular matching.


function render(template, data) {
    // The template string is regular /\{\{(\w+)\}\}/, plus g is the global matching pattern, and each match will call the following function
    let computed = template.replace(/\{\{(\w+)\}\}/g, function(match, key) {
        // match: matched substring; key: parenthesized matched string
        return data[key];
    return computed;

// test
let template = "I'm{{name}},age{{age}},gender{{sex}}";
let data = {
  name: "Zhang San",
  age: 18
console.log(render(template, data)); // I am Zhang San, age 18, gender undefined

Common CSS layout units

Common layout units include pixel (px), percentage (%), em, rem, vw/vh.

(1) Pixel (px) is the basis of page layout. One pixel represents the smallest area that can be displayed on the screen of a terminal (computer, mobile phone, tablet, etc.). Pixels are divided into two types: CSS pixels and physical pixels:

  • CSS pixel: an abstract unit used in CSS for web developers;
  • Physical Pixels: Only related to the hardware density of the device, the physical pixels of any device are fixed.

(2) Percentage (%), when the width or height of the browser changes, the width and height of the components in the browser can be changed with the change of the browser through the percentage unit, so as to achieve a responsive effect. It is generally considered that the percentage of child elements is relative to the immediate parent element.

(3) em and rem are more flexible than px, they are both relative length units, the difference between them: em is relative to the parent element, and rem is relative to the root element.

  • em: Relative length unit of text. The font size relative to the text within the current object. If the font size of the current inline text is not manually set, it is relative to the browser's default font size (default 16px). (a multiple of the font size relative to the parent element).
  • rem: rem is a relative unit added by CSS3, which is a multiple of the font-size of the root element (html element). Function: Use rem to achieve a simple responsive layout. You can use the ratio of the font size in the html element to the screen to set the value of font-size, so that the element changes when the screen resolution changes.

(4) vw/vh is a unit related to the view window, vw represents the width relative to the view window, and vh represents the height relative to the view window. In addition to vw and vh, there are two related units, vmin and vmax.

  • vw: relative to the width of the window, the width of the window is 100vw;
  • vh: Relative to the height of the window, the height of the window is 100vh;
  • vmin: the smaller of vw and vh;
  • vmax: the larger value of vw and vh;

vw/vh is very similar to percentage, the difference between the two:

  • Percentage (%): Most are relative to ancestor elements, but also relative to themselves such as (border-radius, translate, etc.)
  • vw/vm: size relative to the viewport

Tell me the difference between and for...of?

for...of Traversing to get the key value of the object, Gets the key name of the object; will traverse the entire prototype chain of the object, Very poor performance not recommended,and for...of Only traversing the current object does not traverse the prototype chain;
traversing the array, will return all enumerable properties in the array(Include enumerable properties on the prototype chain),for...of Returns only the attribute value corresponding to the subscript of the array;
Summarize: Loops are mainly for traversing objects,Not suitable for traversing arrays; for....of Loops can be used to iterate over arrays, array-like objects, strings, Set,Map as well as Generator object

There are multiple pictures on the page, what is the loading performance of HTTP?

  • Under HTTP 1, the maximum number of TCP connections a browser makes to a domain name is 6, so it will request multiple times. It can be solved with multi-domain deployment. This can increase the number of simultaneous requests and speed up the acquisition of page images.
  • Under HTTP 2, many resources can be loaded in an instant, because HTTP 2 supports multiplexing and can send multiple HTTP requests in one TCP connection.

How does the new operator work?

The execution process of the new operator:

(1) First create a new empty object

(2) Set the prototype, set the prototype of the object to the prototype object of the function.

(3) Let the this of the function point to this object, execute the code of the constructor (add properties to this new object)

(4) Determine the return value type of the function. If it is a value type, return the created object. If it is a reference type, an object of this reference type is returned.


function objectFactory() {
  let newObject = null;
  let constructor =;
  let result = null;
  // Check if an argument is a function
  if (typeof constructor !== "function") {
    console.error("type error");
  // Create a new empty object whose prototype is the prototype object of the constructor
  newObject = Object.create(constructor.prototype);
  // Point this to the new object and execute the function
  result = constructor.apply(newObject, arguments);
  // Judgment return object
  let flag = result && (typeof result === "object" || typeof result === "function");
  // Judgment return result
  return flag ? result : newObject;
// Instructions
objectFactory(Constructor, Initialization parameters);

Array flattening

Array flattening is to flatten a multi-layer array such as [1, [2, [3]]] into a layer of [1, 2, 3]. Use Array.prototype.flat to flatten a multi-layer array directly into one layer:

[1, [2, [3]]].flat(2)  // [1, 2, 3]

Now is to achieve the effect of flat.

ES5 implementation: recursion.

function flatten(arr) {
    var result = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        if (Array.isArray(arr[i])) {
            result = result.concat(flatten(arr[i]))
        } else {
    return result;

ES6 implementation:

function flatten(arr) {
    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr);
    return arr;

Event Loop Mechanism (Event Loop)

Event Loop, which tells us the execution order of javaScript code as a whole, is Event Loop, a mechanism used by browsers or Node s to solve the problem of not blocking a single-threaded javaScript runtime, that is, we often use asynchronous principle s.

Execute the Script script first, then clear the micro-task queue, then start the next round of event loop, continue to execute the macro task first, then clear the micro-task queue, and so on.

  • Macro task: Script/setTimeout/setInterval/setImmediate/I/O/UI Rendering
  • Microtask: process.nextTick()/Promise

The appealed setTimeout and setInterval are all task sources, and what really enters the task queue is the tasks they dispatch.


  • setTimeout = setInterval a queue
  • setTimeout > setImmediate
  • process.nextTick > Promise
for (const macroTask of macroTaskQueue) {  
  for (const microTask of microTaskQueue) {    

lazy loading concept

Lazy loading, also known as lazy loading and on-demand loading, refers to the delayed loading of image data in long web pages, which is a better way to optimize web page performance. In a relatively long web page or application, if there are many pictures, all the pictures are loaded, and the user can only see that part of the picture data in the visible window, which wastes performance.

If you use lazy loading of images, you can solve the above problems. Images outside of the visualization area are not loaded until the screen is scrolled, but are loaded when the screen is scrolled. This makes web pages load faster and reduces server load. Lazy loading is suitable for scenarios with many images and long page lists (long lists).

Bubble sort -- time complexity n^2

Topic Description: Implementing a Bubble Sort

The implementation code is as follows:

function bubbleSort(arr) {
  // cache array length
  const len = arr.length;
  // The outer loop is used to control how many rounds of comparison + exchange from start to finish
  for (let i = 0; i < len; i++) {
    // The inner loop is used to complete the repeated comparison + exchange in each round of traversal
    for (let j = 0; j < len - 1; j++) {
      // If the number in front of the adjacent element is greater than the number in the back
      if (arr[j] > arr[j + 1]) {
        // exchange both
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
  // return array
  return arr;
// console.log(bubbleSort([3, 6, 2, 4, 1]));

Why do you need browser caching?

For the browser's cache, it is mainly aimed at the static resources of the front end. The best effect is to pull the corresponding static resources after initiating the request and save them locally. If the static resources of the server have not been updated, then the next time the request is made, it can be read directly from the local. If the static resources of the server have been updated, then when we request again, we will go to the server to pull the new resources and save them. locally. This greatly reduces the number of requests and improves the performance of the website. This uses the browser's caching strategy.

The so-called browser cache means that the browser stores the static resources requested by the user in the local disk of the computer. When the browser accesses it again, it can be loaded directly from the local, and there is no need to go to the server to request it.

Using browser caching has the following advantages:

  • Reduce the load on the server and improve the performance of the website
  • Faster loading of client web pages
  • Reduced redundant network data transfer

Usage scenarios for the difference between Promise.all and Promise.race

(1) Promise.all Promise.all can wrap multiple Promise instances into a new Promise instance. At the same time, the return values ​​of success and failure are different. When it succeeds, it returns an array of results, and when it fails, it returns the value of the first reject ed failure state.

In Promise.all, an array is passed in, and the return is also an array, and it will be mapped. The values ​​returned by the incoming promise object are arranged in the array in order, but note that the order of their execution is not in accordance with Sequential, unless the iterable is empty.

It should be noted that the order of data in the array of successful results obtained by Promise.all is the same as the order of the array received by Promise.all, so that when multiple requests are sent and data is obtained and used according to the order of requests, you can Use Promise.all to resolve.


As the name implies, Promse.race means running, which means that whichever result in Promise.race([p1, p2, p3]) gets the fastest result will be returned, regardless of whether the result itself is a success state or a failure state. When you want to do something, you can't do it for a long time, you can use this method to solve it:


Convert list to tree structure

Topic description:

        id: 1,
        text: 'Node 1',
        parentId: 0 //Here, 0 is used as the top-level node
        id: 2,
        text: 'Node 1_1',
        parentId: 1 //Use this field to determine the child parent

        id: 1,
        text: 'Node 1',
        parentId: 0,
        children: [
                text: 'Node 1_1',

The implementation code is as follows:

function listToTree(data) {
  let temp = {};
  let treeData = [];
  for (let i = 0; i < data.length; i++) {
    temp[data[i].id] = data[i];
  for (let i in temp) {
    if (+temp[i].parentId != 0) {
      if (!temp[temp[i].parentId].children) {
        temp[temp[i].parentId].children = [];
    } else {
  return treeData;


Description: Wait until all promises return results, then return a promise instance.


Promise.allSettled = function(promises) {
    return new Promise((resolve, reject) => {
        if(Array.isArray(promises)) {
            if(promises.length === 0) return resolve(promises);
            let result = [];
            let count = 0;
            promises.forEach((item, index) => {
                    value => {
                        result[index] = {
                            status: 'fulfilled',
                            value: value
                        if(count === promises.length) resolve(result);
                    reason => {
                        result[index] = {
                            status: 'rejected'.
                            reason: reason
                        if(count === promises.length) resolve(result);
        else return reject(new TypeError("Argument is not iterable"));

Tags: Javascript Front-end

Posted by Shaudh on Mon, 12 Sep 2022 21:19:06 +0300