The article will be updated continuously

1. HTTPS Principle (Encrypted certificate)

  1. The client accesses the Web server using an HTTPS URL and must establish an SSL connection with the server
  2. After receiving a request from a client, the Web server sends a copy of the website certificate (including the public key) to the client
  3. Upon receiving a website certificate, the client checks the authority and expiration date of the certificate, and generates a random key if there is no problem
  4. The client uses the public key to encrypt the session secret key and sends it to the server. The server uses its private key to decrypt the session secret key
  5. Then the server and client use the secret key to encrypt the transmission

2. Network security related (XSS attack and CSRF attack principles and defense measures; Token authentication; The cookie and session)

XSS

  1. XSS: Cross Site Scripting attack.

    XSS refers to a malicious attacker who takes advantage of a web site’s failure to escape or filter the data submitted by users, and then adds some code to embed it in the Web page. Enabling access by other users will execute the appropriate embedded code. Thus stealing user information, using user identity to carry out some actions or to the visitor to a virus attack.

  2. The hazards of an XSS attack include:

    1. Steal all kinds of user accounts, such as machine login accounts, user e-bank accounts, and all kinds of administrator accounts

    2, control of enterprise data, including the ability to read, tamper, add, delete enterprise sensitive data

    3, the theft of enterprises with important commercial value of the data

    4. Illegal money transfers

    5. Force email

    6, the website hanging horse

    7. Control the victim’s machine to launch attacks on other websites

  3. Cause analysis

    Main reason: too much trust in the data submitted by the client!

    Solution: do not trust the data submitted by the client, as long as the data submitted by the client should be filtered before the next step.

    Further analysis: the client submitted data itself is needed for the application, but the sick an attacker exploit the trust a web site for the client to submit the data, insert some symbols and JavaScript code in the data, then the data will become part of the application code to, then the attacker can unbridled attacks

    Therefore, we must never trust any data submitted by the client

  4. type

    Persistent (stored) and non-persistent (reflective)

    Persistent type: durable type is the attack code is written into the database, the attack is very harmful, if the site traffic is very large, it will lead to a large number of normal access to the page, will lead to a large number of normal access to the page of the user are attacked. The most typical is the XSS attack on message boards

    Non-persistent: Non-persistent XSS means that when a request is sent, XSS code appears in the URL of the request, is submitted as a parameter to the server, and the server parses and responds. The response consists of XSS code, which is then parsed and executed by the browser. Conceptually, reflective XSS code first appears in the URL, then needs to be parsed by the server, and then the XSS code needs to be attacked after the browser

  5. defense

    There are two ways to defend

    1. Escape characters

    • First of all, you should never trust user input. The most common way to do this is to escape input and output, and escape parentheses, Angle brackets, and slashes

    2. CSP

    • Content Security Policy (CSP) is an additional layer of security that detects and defuses certain types of attacks, including cross-site scripting (XSS) and data injection attacks. Whether it’s data theft, contamination of website content or the distribution of malware, these attacks are the main means

      The primary goal of CSP is to reduce and report XSS attacks that take advantage of the browser’s trust in what it gets from the server. Malicious scripts work in the victim’s browser because the browser trusts the source of the content, even if it doesn’t come from where it’s supposed to.

      CSP gives the server administrator the ability to reduce or eliminate the vectors upon which XSS attacks depend by specifying a valid domain — that is, a valid source of browser-approved executable scripts. A CSP-compliant browser will only execute the script files obtained from the whitelist field, ignoring all other scripts (including inline scripts and HTML event handling properties).

      As an ultimate form of defense, sites that are always not allowed to execute scripts can choose to ban script execution altogether

      CSP is essentially a whitelist. The developer tells the browser exactly what external resources can be loaded and executed. We just need to configure the rules

    How to enable CSP (if CSP is used)

      1. You can specify your Policy using the Content-security-policy HTTP header, like this:
    Set content-security-policy: Policy in the HTTP HeaderCopy the code
      1. How to set meta tags
    Meta HTTP - equiv = "Content ws-security - Policy" Content = "default - SRC 'self'; img-src https://*; The child - SRC "none";" >Copy the code

    Common use cases (for example, setting the HTTP Header)

    • A site administrator who wants all content to come from the same source on the site (not including subdomains) is only allowed to load site resources
    The Content ws-security - Policy: the default - SRC 'self'Copy the code
    • A webmaster allows content from a trusted domain name and its subdomains (the domain name does not have to be the same as the domain where the CSP is set up)
    The Content ws-security - Policy: the default - the SRC 'self' *. Trusted.comCopy the code
    • A webmaster allows users of web applications to include images from any source in their own content, but limits audio or video to trusted resource providers, and all scripts must be sourced from trusted code from a specific host server.
    The Content ws-security - Policy: the default - SRC 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.comCopy the code
    • Only HTTPS images can be loaded
    Content-Security-Policy: img-src https://*
    Copy the code
    • Allows loading of frameworks from any source
    The Content ws-security - Policy: child - SRC 'none'Copy the code

    In this case, the developer has to configure the correct rules so that even if the site has vulnerabilities, the attacker cannot execute its attack code, and the CSP compatibility is good.

CSRF

1. Basic Concepts

Cross-site Request Forgery (CSRF), also known as “One Click Attack” or Session Riding, is usually abbreviated to CSRF or XSRF. It is a malicious use of a website. Although it may sound like cross-site scripting (XSS), it is very different from XSS, which exploits trusted users within a site, while CSRF exploits trusted sites by making requests disguised as trusted users. CSRF attacks tend to be less popular (and therefore have fewer resources to defend against) and harder to defend against than XSS attacks, so they are considered more dangerous than XSS.

2 the principle of

The idea is that the attacker constructs a back-end request address and induces the user to click or automatically initiate the request through some way. If the user is logged in, the back end assumes that the user is doing the operation and does the corresponding logic

In other words, to complete a CSRF attack, the victim must complete two steps in sequence: 1. Log in to a trusted website and generate cookies locally; 2. Visit a dangerous website without logging out of the trusted website

You may be wondering: if I don’t meet one of these two conditions, I won’t receive a CSRF attack. Indeed, but you cannot guarantee the following situation: 1, you can’t make sure that you log in a website, no longer open a TAB page and access to other page 2 you can’t make sure that you close the browser after your local cookies expire, immediately your last session has ended. (in fact, close the browser cannot end a session,)

3 Hazards (what CSRF can do)

Attackers steal your identity and send malicious requests in your name. CSRF can do things like send emails in your name, steal your account and even buy goods, transfer virtual currency, personal privacy and property security

CSRF attacks originate from the WEB’s implicit authentication mechanism! The WEB’s authentication mechanism can guarantee that a request came from a user’s browser, but it cannot guarantee that the request was sent with the user’s approval!

4 How to Defend yourself

The defense against CSRF attacks can follow the following rules:

  • The GET request does not modify the data
  • Do not allow third party websites to access cookies
  • Block third party websites from requesting interfaces
  • The request comes with authentication information, such as a verification code or Token

SameSite

  • You can set the SameSite property on cookies, which means that cookies are not sent with cross-domain requests, and can greatly reduce CSRF attacks, but this property is not currently compatible with all browsers

Verify the Referer HTTP header

  • For requests that need to be protected against CSRF, we can verify the Referer to determine whether the request was initiated by a third party site.

The Token server verifies the Token

  • The server sends a random Token for the server to check the Token. Each time it sends a request, it carries the Token and the server verifies whether the Token is valid

Verification code

  • The idea is that each user submission requires the user to fill in a random string of images in the form. This solution can fully solve CSRF, but personally feel that the usability aspect seems not very good, and heard that the use of captcha image involves a Bug called MHTML, may be affected in some versions of Microsoft IE.

3. Cache mode

The strong cache will fetch the cached file, while the negotiated cache will send a request to the server to confirm the validity of the document.

Details: mp.weixin.qq.com/s/G5FIrWOts…

Generally, static resources such as JS and CSS are cached strongly, while HTML is cached through negotiation (no hash).

4. Cross-domain mode (proxy, CORS policy, JSONP script cross-domain, Webket…)

  1. The specific implementation
  2. In what scenarios are they used

1. The json across domains

The <script> tag SRC attribute is used to send a GET request with a callback parameter. The server pieces the data returned by the interface into the callback function and returns it to the browser. The browser parses and executes the callback. The front end gets the data returned by the callback function.

Disadvantages of JSONP: You can only send a GET request.

2. Cross-domain Resource Sharing (CORS)

CORS is a W3C standard that stands for Cross-Origin Resource Sharing. It allows browsers to make XMLHttpRequest requests to cross-source servers, overcoming the limitation that AJAX can only be used from the same source. CORS requires both browser and server support. Currently, all browsers support this function. The value of Internet Explorer cannot be lower than IE10.

Browsers divide CORS cross-domain requests into simple requests and non-simple requests.

As long as the following two conditions are met, it is a simple request

(1) Use one of the following methods:

  • head
  • get
  • post

(2) The requested Heder is

  • Accept
  • Accept-Language
  • Content-Language
  • Content-type: Only three values: Application/X-www-form-urlencoded, Multipart /form-data, text/plain

If both of the above conditions are not met, it is a non-simple request. The browser handles the two differently.

A simple request

For simple requests, the browser issues the CORS request directly. Specifically, add an Origin field to the header.

GET /cors HTTP/1.1 Origin: http://api.bob.com Host: api.alice.com Accept-language: EN-US Connection: Keep alive - the user-agent: Mozilla / 5.0...Copy the code

In the header above, the Origin field is used to indicate the source (protocol + domain + port) from which the request is coming. The server uses this value to decide whether to grant the request.

The response header field set by a CORS request begins with access-control – :

1) access-control-allow-origin: This parameter is mandatory

Its value is either the value of the Origin field at the time of the request, or an * to accept requests for any domain name.

2) access-control-allow-Credentials: Optional

Its value is a Boolean value indicating whether cookies are allowed to be sent. By default, cookies are not included in CORS requests. Set to true, indicating that the server explicitly permits the Cookie to be included in the request and sent to the server. This value can only be set to true. If the server does not want the browser to send cookies, remove this field.

3) Access-control-exposure-headers: Optional

When CORS requests, the XMLHttpRequest object’s getResponseHeader() method gets only six basic fields: Cache-control, content-language, Content-type, Expires, last-modified, and Pragma. If you want to get other fields, you must specify them in access-Control-exposure-headers. The example above specifies that getResponseHeader(‘ FooBar ‘) returns the value of the FooBar field.

Non-simple request

Non-simple requests are requests that have specific requirements for the server, such as the request method being PUT or DELETE, or the content-type field being application/ JSON. For CORS requests that are not simple requests, an HTTP query request is added before the formal communication, called a “preflight” request.

Preview the request

The “precheck” request uses the request method OPTIONS, indicating that the request is intended to be asked. In the request header, the key field is Origin, which indicates the source from which the request came. In addition to the Origin field, the precheck request header contains two special fields.

OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0..
Copy the code

1) access-control-request-method: This parameter is mandatory

To list which HTTP methods are used for CORS requests from the browser, such as PUT.

2) Access-control-request-headers: Optional

This field is a comma-separated string that specifies the additional Header field that will be sent for browser CORS requests, such as x-custom Header in the previous example.

Response to a Precheck Request After the server receives a precheck Request, it checks the Origin, Access-control-Request-method, and Access-control-Request-headers fields, confirms that cross-source requests are allowed, and responds.

In addition to the key access-control-allow-origin field, the other CORS related fields are as follows:

1) access-control-allow-methods: Mandatory

Its value is a comma-separated string indicating all the cross-domain request methods supported by the server. Note that all supported methods are returned, not just the one requested by the browser. This is to avoid multiple precheck requests.

2) Access – Control – Allow – Headers

The Access-control-allow-headers field is required if the browser Request includes the Access-control-Request-headers field. It is also a comma-separated string indicating all header fields supported by the server, not limited to fields requested by the browser in precheck.

3) access-control-allow-Credentials: Optional

This field has the same meaning as a simple request.

4) access-control-max-age: Optional

Specifies the validity period of the precheck request, in seconds.

3. Nginx agent cross-domain

Nginx proxy cross-domain, essence and CORS cross-domain principle, through the configuration file to set the request response header access-control-allow-origin… And other fields.

1) NGINx configuration to solve iconfont cross-domain

Browser cross-domain access js, CSS, and img conventional static resources are the same-origin policy permission, but iconfont font file (eot | otf | the vera.ttf | woff | SVG) exception, at this time in nginx server to add the following configuration static resources.

location / {
  add_header Access-Control-Allow-Origin *;
}
Copy the code

2) NGINx reverse proxy interface cross-domain

Cross-domain problem: The same-origin policy applies only to browsers. The server side only uses THE HTTP protocol to call the HTTP interface, and does not need the same origin policy, so there is no cross-domain problem.

Implementation idea: Through Nginx, configure a proxy server with the same domain name as domain1 and different ports) to act as a jumper, access the interface of domain2 through reverse proxy, and modify the domain information in cookies in the way to facilitate the writing of cookies in the current domain and achieve cross-domain access.

Nginx configuration:

#proxy server {listen 81; server_name www.domain1.com; location / { proxy_pass http://www.domain2.com:8080; # reverse proxy proxy_cookie_domain www.domain2.com www.domain1.com; # Modify cookie index. HTML index. HTM; # When accessing Nignx using middleware proxy interfaces such as Webpack-dev-server, no browser is involved, so there is no same-origin restriction. Add_header access-control-allow-origin http://www.domain1.com is not enabled for the following cross-domain configuration; * add_header access-control-allow-credentials true; * add_header access-control-allow-credentials true; }}Copy the code

4. Nodejs middleware proxy is cross-domain

Node middleware implements cross-domain proxy. The principle of node middleware is roughly the same as that of Nginx. In both cases, a proxy server is set up to forward data.

1) Non-VUE framework cross-domain

Build a proxy server using Node + Express + HTTP-proxy-middleware.

  • Front-end code:
var xhr = new XMLHttpRequest(); // Front-end switch: whether the browser reads and writes cookies xhr.withCredentials = true; / / access HTTP proxy - middleware proxy server XHR. Open (' get 'and' http://www.domain1.com:3000/login?user=admin ', true); xhr.send();Copy the code
  • Middleware server code:
var express = require('express'); var proxy = require('http-proxy-middleware'); var app = express(); App. Use ('/', the proxy ({/ / agent cross-domain target interface target: 'http://www.domain2.com:8080', changeOrigin: // Modify the response header to allow onProxyRes with cookie: function(proxyRes, req, res) { res.header('Access-Control-Allow-Origin', 'http://www.domain1.com'); res.header('Access-Control-Allow-Credentials', 'true'); CookieDomainRewrite: 'www.domain1.com' // can be false, indicating no modification})); app.listen(3000); console.log('Proxy server is listen at port 3000... ');Copy the code

2) Cross-domain vUE framework

Node + vue + webpack + webpack-dev-server project, cross-domain request interface, directly modify webpack.config.js configuration. In the development environment, vue rendering service and interface proxy service are the same Webpack-dev-server, so there is no cross-domain between the page and the proxy interface.

Webpack.config.js part configuration:

module.exports = { entry: {}, module: {}, ... devServer: { historyApiFallback: true, proxy: [{ context: '/login', target: 'http://www.domain2.com:8080', / / agent cross-domain target interface changeOrigin: true, secure: false, / / when certain HTTPS proxy service error with cookieDomainRewrite: 'www.domain1.com' // can be false, meaning no change}], noInfo: true}}Copy the code

5, document.domain + iframe cross-domain

This solution applies only to cross-domain scenarios where the primary domain is the same but the subdomains are different. Implementation principle: two pages through JS mandatory set document.domain as the basis of the primary domain, the implementation of the same domain.

6. Location. hash + iframe Cross-domain

Implementation principle: A wants to communicate with B across domains through the middle page C. Three pages. Different domains pass values using the location.hash of iframe, and the same domains directly communicate with each other by JS access.

Specific implementation: A domain: a.HTML -> B domain: B.html -> A domain: C.tml, A and B different domain can only hash value one-way communication, B and C also different domain can only one-way communication, but C and A domain, so C can access all objects of A page through parent. Parent.

7, window.name + iframe cross-domain

The unique feature of the window.name property is that the name value will persist across different pages (or even different domain names), and very long name values (2MB) can be supported.

8. PostMessage cross-domain

PostMessage is an API in HTML5 XMLHttpRequest Level 2 and is one of the few window properties that can be operated across domains. It can be used to solve the following problems:

  • Data transfer between the page and the new window it opens
  • Messaging between multiple Windows
  • Page with nested IFrame message delivery
  • Cross-domain data transfer for the three scenarios above

The postMessage(data,origin) method takes two arguments:

  • Data: The HTML5 specification supports any basic type or replicable object, but some browsers only support strings, so it’s best to serialize with json.stringify () when passing arguments.
  • Origin: protocol + host + port number. It can also be set to “*”, indicating that it can be passed to any window, or “/” if you want to specify the same origin as the current window.

9. WebSocket protocol cross-domain

WebSocket Protocol is a new HTML5 protocol. It realizes full-duplex communication between browser and server and allows cross-domain communication. It is a good implementation of Server push technology. The native WebSocket API is not easy to use, so we use socket. IO, which encapsulates the WebSocket interface nicely, providing a simpler, more flexible interface, and downward compatibility for browsers that don’t support WebSocket.

summary

These are nine common cross-domain solutions. Jsonp (only support get request, support old IE browser) is suitable for loading js, CSS, IMG and other static resources of different domain names; CORS (support all types of HTTP requests, but the browser IE10 does not support) is suitable for ajax various cross-domain requests; Nginx proxy cross-domain principle and NodeJS middleware cross-domain principle are similar, both set up a server, directly request HTTP interface on the server side, this is suitable for the front-end project before and after the separation of the back-end interface. Document. domain+iframe is suitable for cross-domain requests with the same primary domain name but different subdomains. PostMessage and WebSocket are both new HTML5 features that are not very compatible and only work with major browsers and IE10+.

5. TCP three handshakes and four waves

One or three handshakes

  • The client sends a packet with the bitcode SYN=1 and randomly generates seq number=1234567 to the server. The server knows that the client is asking for an online connection.
  • Ack number=(client SEq +1), ACK number=(client SEq +1), ACK number=(client SEq +1), ACK number=(client SEq +1);
  • After receiving the ack number, the client checks whether the ack number is correct, that is, seq number+1 sent the first time, and whether the ack code is 1. If the ack number is correct, the client sends ack number=(seq+1 sent by the server),ack=1, If seQ and ACK =1, the connection is established successfully. (Client: Ok, HERE I come)

Why does HTTP require three handshakes to establish a connection, instead of two or four?

A: Three times is the least safe, two times is unsafe, and four times is a waste of resources;

TCP connection closing process

  1. The Client sends a FIN packet to the Server, indicating that the Client actively wants to close the connection, enters the FIN_WAIT_1 state, and waits for the Server to return an ACK packet. After that, the Client can no longer send data to the Server, but it can read data.

  2. After receiving the FIN packet, the Server sends an ACK packet to the Client and enters the CLOSE_WAIT state. After that, the Server cannot read data but can continue to send data to the Client.

  3. After receiving the ACK packet returned by the Server, the Client enters the FIN_WAIT_2 state and waits for the Server to send the FIN packet.

  4. After sending data, the Server sends the FIN packet to the Client. Then the Server enters the LAST_ACK state and waits for the Client to return the ACK packet. After that, the Server can neither read data nor send data.

  5. After receiving a FIN packet, the Client sends an ACK packet to the Server. Then the Client enters the TIME_WAIT state and waits 2MSL to ensure that the Server has received the ACK packet. Finally, the Client returns to the CLOSED state to release network resources.

  6. After receiving the ACK packet returned by the Client, the Server returns to the CLOSED state and releases network resources

Why four waves?

TCP is a full-duplex channel. What is full-duplex is that the client and the server establish two channels. Channel 1: The output of the client connects to the input of the server; Channel 2: Client input connects to server output. Both channels can work at the same time: the client can send signals to the server and the server can also send signals to the client. So this is what happens when you close two channels:

Client: I’m going to close the input channel.

Server: Ok, you close, I will close this channel.

Server: I’m going to close the input channel as well.

Client: Ok you close, I will close this channel.

Fibonacci series

1. The recursion

function f(n) { if (n === 1 || n === 2) { return 1; } else { return f(n-1) + f(n-2); }}Copy the code

Time complexity: O(2^N)

Space complexity: O(N)

The time complexity is exponential and belongs to the explosive increment function. We should avoid such complexity in the programming.

Recursive Fibonacci sequence code implementation is more concise, but when n is relatively large will cause stack overflow, unable to achieve the required function.

  1. The tail call
function f(n, ac1=1, ac2=1) {
	if (n<=2) {
    	return ac2;
    } 
    return f(n-1, ac2, ac1+ac2);
}
Copy the code
  1. The iterator
function* f(){ let [prev, curr] = [0, 1]; // for(;;) = while(1) for(;;) { yield curr; [prev, curr] = [curr, prev + curr]; } } for(let n of f()) { if (n > 1000) break; console.log(n); }Copy the code
  1. Recursion with caching
function memozi(fn) {
	var r = {};
    return function(n) {
    	if (r[n] == null) {
        	r[n] = fn(n);
            return r[n];
        } else {
        	return r[n];
        }
    }
}

var fibfn = memozi(function(n) {
	if (n==0) {
    	return 0;
    } else if (n==1) {
    	return 1;
    } else {
    	return fibfn(n-1) + fibfn(n-2)
    }
})
Copy the code

Closure knowledge is used here, so I asked “closure” knowledge (see question 15 for details).

7. Programming problem

Given a string containing only ‘(‘, ‘)’, ‘{‘, ‘}’, ‘[‘, ‘]’, determine whether the string is valid. A valid string must meet the following requirements: The opening parenthesis must be closed with the same type of closing parenthesis. The opening brackets must be closed in the correct order. Note that an empty string can be considered a valid string

var isValid = function(s) { const n = s.length; if (n % 2 === 1) { return false; } const pairs = new Map([ [')','('], [']','['], ['}','{'] ]); const stk = []; for(let i=0; i<s.length; i++) { if (pairs.has(s[i])) { if (! stk.length || stk[stk.length-1] ! == pairs.get(s[i])) { return false; } stk.pop(); } else { stk.push(s[i]); } } return ! stk.length; }Copy the code

8. There are two data structures for submitting data

The difference and principle between URL value and form submission

The difference between:

1, URL pass value is get,from form is post, get is to get data from the server, post is to send data to the server

2. In GET mode, the server uses Request.QueryString to obtain the variable value; in POST mode, the server uses Request.Form to obtain the submitted data.

3. The amount of data to be transmitted by get is small and cannot be larger than 2KB. The amount of data transmitted by POST is large. Therefore, the default value is unrestricted.

4. The GET security is very low, while the POST security is high

9. Optimize performance

    1. Reduce HTTP requests
    1. Using HTTP2
    1. Use server-side rendering
    1. Static resources use the CDN
    1. Place the CSS at the head of the file and the JavaScript file at the bottom
    1. Use the font icon iconfont instead of the picture icon
    1. Make good use of the cache and do not load the same resource repeatedly
    1. The compressed file
    1. Image optimization
    1. Webpack is used to load the code on demand and extract the code from the third library to reduce the redundancy of ES6 to ES5
    1. Reduce redrawings and rearrangements
    1. Using event Delegates
    1. Note the locality of the program
    1. If – else contrast the switch
    1. A lookup table
    1. Avoid page stuttering
    1. Use requestAnimationFrame to implement visual changes
    1. Use Web Workers
    1. Using bit operations
    1. Do not override native methods
    1. Reduce the complexity of CSS selectors
    1. Use Flexbox instead of the older layout model
    1. Use the Transform and opacity property changes to animate
    1. Use rules wisely to avoid over-optimization

10. Process and optimization of browser from input to page rendering

  • 1. The DNS
  • 2. TCP phase
  • 3. The stage of HTTP
  • 4. Parse/render phase
  • Layout/render the page

Optimization:

1. The DNS pre-resolution function tells the browser that we may obtain resources from a specific URL in the future. When the browser actually uses a resource in the domain, the DNS pre-resolution function is completed as soon as possible.

Step 1: Enable or disable DNS preresolution

You can do this by sending the X-DNs-Prefetch -Control header on the server side. Or use a meta tag with the value http-equiv in the document:

<meta http-equiv="x-dns-prefetch-control" content="on">
Copy the code

Note that in some advanced browsers, DNS preresolution is enabled for all hyperlinks (<a> tabs) on the page by default. However, many browsers disable DNS preresolution of hyperlinks by default if the HTTPS protocol is used on the page. If you add the above line of code, you force the browser’s preparsing to open. (If you can say that in an interview, it’s a real asset.)

Step 2: Perform DNS pre-resolution on the specified domain name

If we might get an image or audio resource from Smyhvae.com in the future, add the following to the tag at the top of the document:

<link rel="dns-prefetch" href="http://www.smyhvae.com/">
Copy the code

When we request a resource from this URL, we no longer need to wait for DNS resolution. This technique is particularly useful for using third-party resources.

11. Anti-shaking and throttling functions

1. The image stabilization (debounce)

function debounce (f, wait) { let timer return (... args) => { clearTimeout(timer) timer = setTimeout(() => { f(... args) }, wait) } }Copy the code

Usage scenarios

  • 1. Buttons such as login and SMS should be avoided to prevent users from clicking too fast and sending multiple requests, which requires anti-shaking
  • 2. When the browser window size is adjusted, the resize times are too frequent, resulting in excessive calculation. At this time, it needs to be in place once, so the shaking is used
  • 3. The text editor saves it in real time, and saves it one second after no change operation

2. The throttle

function throttle (f, wait) { let timer return (... args) => { if (timer) { return } timer = setTimeout(() => { f(... args) timer = null }, wait) } }Copy the code

Usage scenarios

  • 1. Scroll event. Position information is calculated every second
  • 2. The browser plays events and calculates the progress every second
  • 3. Real-time search and send requests in the input box to display the drop-down list, and send the request every second (also can do anti-shaking)

Summary (brief answer)

  • Anti-shake: prevents jitter. Event triggering per unit time will be reset to prevent events from being triggered multiple times by friendly fire. The code implementation is reset in clearTimeout. Shaking can be compared to waiting for an elevator, as long as one person comes in, it needs to wait a little longer. In business scenarios, avoid repeated submission when the login button is clicked multiple times.
  • Throttling: Controls traffic. Events can be triggered only once per unit time, which is similar to the Rate Limit on the server. Lock timer=timeout; The timer = null. Throttling can be likened to going through a traffic light, every time you wait for a red light, you can go through a batch.

12. The principle of THE ES6 Promise, the more detailed the better, is different from the Generator

Write Promise(Easy Version)

function myPromise(fn) {
    this.cbs = [];
    const resolve = (value) => {
        setTimeout(() => {
            this.data = value;
            this.cbs.forEach((cb) => cb(value));
        })
    }
    fn(resolve);
}
myPromise.prototype.then = function (onResolved) {
    return new myPromise((resolve) => {        
        this.cbs.push(() => {
            const res = onResolved(this.data);
            if (res instanceof myPromise) {
                res.then(resolve);
            } else {
                resolve(res);
            }
        });
    });
}
export default myPromise;

Copy the code

Promise details juejin.cn/post/690555…

13. How to disable js access cookie

Set-Cookie: name=value; HttpOnly

14. The left side is fixed and the right side is adaptive to the layout of two columns

HTML layout:

< div class = "outer" > < div class = "sidebar" > fixed width area (sidebar) < / div > < div class = "content" > adaptive area (content) < / div > < / div > < div class="footer">footer</div>Copy the code

Methods:

1. Float the left div and set margin-left for the right div

/* method 1*/.outer{overflow: hidden; border: 1px solid red; } .sidebar{float: left; width:200px; height: 150px; background: #BCE8F1; } .content{margin-left:200px; height:100px; background: #F0AD4E; }Copy the code
  1. flex
/* Method 2*/.outer7{display: flex; border: 1px solid red; } .sidebar7{flex:0 0 200px; height:150px; background: #BCE8F1; } .content7{flex: 1; height:100px; background: #F0AD4E; }Copy the code

Flex is arguably the best solution, less code and easy to use. But there is compatibility, and one day everyone will switch to a modern browser and it will work.

Note that one of the default flex container properties is :align-items: stretch; . This property causes the effect of the columns being equal in height. To make both boxes height automatic, you need to set: align-items: flex-start;

  1. Float + BFC method
/* Method 3*/.outer6{overflow: auto; border: 1px solid red; } .sidebar6{float: left; height:150px; background: #BCE8F1; } .content6{overflow:auto; height:100px; background: #F0AD4E; }Copy the code

This scenario also utilizes the left float, but the right box is passed through overflow: auto; The BFC is formed so that the right box does not overlap with the floating elements.

Extension question: Since flex layout is used in the code, I asked for flex layout knowledge

Flex, short for Flexible Box, means “Flexible layout” and is used to provide maximum flexibility for box-shaped models. Any container can be specified as a Flex layout. There are two kinds of containers, block Flex and inline Flex.

.box{ display: flex; /*webkit needs to be prefixed */ /*display:inline-flex; * /}Copy the code

The Flex layout has two layers. The elements that use the Flex layout are called Flex containers, and their children are automatically Flex items, or items. Note: Flex is different from block. Float,clear,vertical-align properties of children of the Flex container are invalid.

Flex layout:

  1. The Flex container has two axes: the horizontal axis is the x axis (main axis) and the vertical axis is the y axis (cross axis).

  2. Flex container properties:

  • Flex-direction: Determines the direction of the project.

  • Flex-wrap: How to wrap lines when one axis is not fit.

  • Flex-flow: short for the flex-direction and flex-wrap properties. The default is row nowrap.

  • Embryo-content: Defines the alignment of items on the spindle. (justify)

  • Align-items: Defines how items are aligned on cross axes.

  • Align-content: Defines the alignment of multiple axes. This property does not work if the project has only one axis. (Line feeds produce multiple axes)

Flex Item attribute:

  • Order: Defines the order in which items are arranged. The smaller the value, the higher the order, the default is 0.

  • Flex-grow: Defines the magnification of the project, so that if all projects have a Flex-grow attribute of 1, they will equally divide the remaining space (if any). If one project’s Flex-grow property is 2 and the others are all 1, the former will take up twice as much remaining space as the others.

  • Flex-shrink: Defines the scale by which the project is shrunk. The default is 1. If all projects have a Flex-shrink property of 1, they will be shrunk equally when there is not enough space. If one project has a Flex-shrink property of 0 and all other projects have a flex-shrink property of 1, the former does not shrink when space is scarce.

  • Flex-basis: Defines the main size of the project before the extra space is allocated.

  • Flex: short for flex-grow, flex-shrink, and Flex-basis. Default is 0, 1 auto. The last two attributes are optional.

  • Align-self: Allows individual items to have a different alignment than other items, overriding the align-items property. The default value is Auto, which means that the align-items property of the parent element is inherited, and is equivalent to stretch if there is no parent element.

15. Closure

What is a “closure”.

A closure is the sum of the "function" and the "variables accessible within the function" (also known as the environment).Copy the code

What “closures” do.

Closures are often used to "indirectly access a variable." In other words, "hide a variable."Copy the code

Rumors about closures

Closures cause memory leaks?

Fault.

Whoever said that has no idea what a memory leak is. A memory leak is when a variable that you do not use (cannot access) still occupies memory space and cannot be reused.

The variables in the closure are exactly what we need (lives), so why is it a memory leak?

How did this rumor come about?

Because Internet explorer. There is a bug in IE where IE fails to retrieve variables referenced in closures after we have finished using them.

This is an IE problem, not a closure problem.

In detail: zhuanlan.zhihu.com/p/22486908

16.VUE bidirectional data binding principles

1. Vue bidirectional data binding is implemented through data hijacking combined with publish/subscribe mode. That is to say, data and view are synchronized.

2. Core: The core of VUE bidirectional data binding is the object.defineProperty () method;

3. Introduce the object.defineProperty () method

(1) Object. DefineProperty (obj, prop, descriptor); (2) Object. DefineProperty (obj, prop, descriptor); (3) Object.

(2) In simple terms, this method is used to define a value. We use its get method when we call it, and we use its set method when we assign a value to this property;

17. Webpack packaging process

Overview of the WebPack packaging process

The running process of WebPack is a serial process. From start to finish, the following processes are executed in sequence:

  • 1. Initialize parameters
  • 2. Start compiling the initial Compiler object obtained in the previous step, load all configured plug-ins, and start compiling through the run method of the execution object
  • 3. Determine Entry Locate all Entry files according to the Entry in the configuration
  • 4. Compile the module. Start from the entry file, call all configured loaders to compile the module, find out the module that the module depends on, and repeat this step until all the entry dependent files have been processed in this step
  • 5. Complete module compilation. After all modules are translated by Loader in step 4, the final compiled content of each module and their dependencies are obtained
  • 6. Output resources: According to the dependency between the entry and the modules, assemble them into chunks containing multiple modules, and then convert each Chunk into a separate file and add it to the output list. This is the last chance to modify the output content
  • 7. Output is complete: After determining the output content, determine the output path and file name according to the configuration, and write the file content to the file system.

In this process, Webpack broadcasts specific events at specific points in time, the plug-in listens to the event of interest and executes specific logic, and the plug-in can invoke the API provided by Webpack to change the results of Webpack. In fact, the above seven steps can be summarized into three processes: initialization, compilation, and output, and this process is actually an extension of the basic model mentioned above.

18. The difference between Map and Object

  • In an Object, the key must be a simple data type (integer, string, or symbol). In a Map, it can be any type supported by JavaScript. This means that an Object can be used as the key of a Map element.

  • The order of Map elements follows the order of insertion, whereas the order of Object elements does not.

  • Map inherits from Object.

  • The new instance

    • Object supports the following methods to create new instances:
    var obj = {... }; var obj = new Object(); var obj = Object.create(null);Copy the code
    • Map only supports one of the following build methods:
    var map = new Map([[1, 2], [2, 3]]); // map = {1 => 2, 2 => 3}
    Copy the code
  • The data access

    • If a Map wants to access an element, it can use the native methods of the Map itself:
    map.get(1) // 2
    Copy the code
    • Objects can be accessed through. And []
    obj.id;
    obj['id'];
    Copy the code
    • Determines whether an element is available in the Map
    map.has(1);
    Copy the code
    • Determining whether an element is an Object requires the following operations:
    obj.id === undefined;
    // 或者
    'id' in obj;
    Copy the code

    In addition to note is that the Object can use Object. The prototype. The hasOwnProperty () to determine whether a key is that the attributes of the Object itself, from the prototype chain inherited attributes are not included in the calculation.

  • Add a new data

    • Map can be operated using set() :
    Map.set (key, value) // Map overwrites the value when the key already existsCopy the code
    • Object adds a new property that can be used:
    obj['key'] = value; obj.key = value; // Object will also be overriddenCopy the code
  • Delete the data

    • There is no native delete method in Object. We can use the following method:
    delete obj.id; Obj. id = undefinedCopy the code

    Note that using delete actually removes the property from the object, whereas using undefined only changes the value to undefined. Properties are still on the object, which means you’re using for… The in… When you go through it, you’re still going to access that property.

    • Map has a native delete method to delete elements:
    var isDeleteSucceeded = map.delete(1); console.log(isDeleteSucceeded ); // delete map.clear(); // delete map.clear();Copy the code
  • Get the size

    • Map has its own size attribute and can maintain the size change itself.

    • An Object needs to be computed using object.keys ()

    console.log(Object.keys(obj).length); 
    Copy the code
  • Iterating

    Map itself supports iteration. Object does not.

    How do you determine if a type supports iteration? You can use the following methods:

    console.log(typeof obj[Symbol.iterator]); // undefined
    console.log(typeof map[Symbol.iterator]); // function
    Copy the code

When to use Map and When to use Object?

  • When storing simple data types and the key is either a string or an integer or a Symbol, Object is preferred because it can be created as a character variable, which is more efficient.

  • Use Object when you need to access attributes or elements in their own logic

  • JSON directly supports Object, but does not support Map

  • Maps are pure hashes, and objects have some other inherent logic, so there are performance issues when performing delete. So Map should be used for write and delete intensive cases.

  • A Map maintains the order of the elements in the order they were inserted, whereas an Object does not.

  • Maps perform better when a large number of elements are stored, especially when the type of key cannot be determined at code execution time

19. What happens to a new function

Construct call:

  • Create an entirely new object
  • This object will be wired by the [[Prototype]] execution, linking the new object’s [[Prototype]] to the object referred to by the constructor
  • This new object is bound to the this function call
  • If the function returns no other object, then the function call in the new expression automatically returns the new object

If a function returns an object, then the call to new returns the object returned by the function, otherwise returns the new object created by new

20. De-duplicate arrays

Array.from(new Set([1, 1, 2, 2]))
Copy the code

21. Array flattening

function flatten(arr) {
  let result = [];

  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      result = result.concat(flatten(arr[i]));
    } else {
      result = result.concat(arr[i]);
    }
  }

  return result;
}

const a = [1, [2, [3, 4]]];
console.log(flatten(a));
Copy the code

22. Event Loop

The Event Loop mechanism tells us the execution order of JavaScript code as a whole. An Event Loop is a browser or Node mechanism to solve the problem of JavaScript single thread running without blocking, which is often used in asynchronous principle. The macro task queue is executed, then the microtask queue is executed, and then the next round of event cycle begins, continuing with the macro task queue first, then the microtask queue.

  • Task: macro script/setTimeout/setInterval/setImmediate/I/O/UI Rendering
  • Microtask: process.nexttick ()/Promise

The setTimeout and setInterval of the appeal are the source of the task, and the actual task that enters the task queue is the task that they distribute.

priority

  • SetTimeout = setInterval A queue
  • setTimeout > setImmediate 
  • process.nextTick > Promise

New microtasks generated during the execution of a microtask are not deferred to the next loop, but continue execution in the current loop

Is arguments an array in the function? Class array to array method understand?

It’s array-like, it’s in the duck category, it looks like an array,

  • . The operator
  • Array.from
  • Array.prototype.slice.apply(arguments)

24. Write custom WebPack plug-ins

A typical Webpack plug-in code looks like this:

Class MyWebpackPlugin {constructor(options) {} apply(compiler) {// insert the hook function compiler.hooks.emit. Tap ('MyWebpackPlugin', 'constructor'); (compilation) => {}); } } module.exports = MyWebpackPlugin;Copy the code

The next step is to introduce the plug-in in webpack.config.js.

Module. exports = {plugins:[// pass new MyWebpackPlugin({param:'paramValue'}),]};Copy the code

Webpack instantiates the plug-in object at startup. After initializing the compiler object, Webpack calls the Apply method of the plug-in instance, passing in the compiler object. The plug-in instance registers interested hooks in the Apply method, and Webpack calls the corresponding hooks during execution, depending on the construction phase.

Please Google for details

Implement an EventEmitter

function EventEmitter() { this.__events = {}; } EventEmitter. VERSION = "1.0.0"; EventEmitter.prototype.on = function(eventName, listener) { if (! eventName || ! listener) return; // Determine whether the callback listener(or listener.listener) is the function if (! isValidListener(listener)) { throw new TypeError('listener must be a function'); } var events = this.__events; var listeners = events[eventName] = events[eventName] || []; var listenerIsWrapped = typeof listener === 'object'; If (indexOf(Listeners, listeners) === -1) {listeners. Push (listenerIsWrapped? listener : { listener: listener, once: false }) } return this; } EventEmitter.prototype.emit = function(eventName, Args) {var listeners = this.__events[eventName]; if (! listeners) return; For (var I = 0; i < listeners.length; i++) { var listener = listeners[i]; if (listener) { listener.listener.apply(this, args || []); If (listener.once) {this.off(eventName, listener.listener)}}} return this; } EventEmitter.prototype.off = function(eventName, listener) { var listeners = this.__events[eventName]; if (! listeners) return; var index; for (var i = 0, len = listeners.length; i < len; i++) { if (listeners[i] && listeners[i].listener === listener) { index = i; break; } } if (typeof index ! == 'undefined') { listeners.splice(index, 1, null); } return this; } EventEmitter. Prototype. Once = function (eventName, listener) {/ / call on method, once parameter to true, Return this.on(eventName, {listener: listener, once: True})} EventEmitter. Prototype. AlloOff = function (eventName) {/ / if the eventName, If (eventName && this.__events[eventName]) {this.__events[eventName] = []; } else { this.__events = {}; Function isValidListener(listener) {if (typeof listener === 'function') {return true; } else if (listener && typeof listener === 'object') { return isValidListener(listener.listener); } else { return false; }} function indexOf(array, item) {var result = -1; item = typeof item === 'object' ? item.listener : item; for(var i = 0, len = array.length; i<len; i++) { if (array[i].listener === item) { result = i; break; } } return result; }Copy the code

One solution for communication between different components in the Vue framework is called EventBus. Similar to the idea of EventEmitter, its basic purpose is to use EventBus as a bridge between components. All components share the same event center. They can register to send or receive events, and all components can receive notifications. At its core, the publish-subscribe model is a full-fledged implementation

26. Garbage collection: Free memory and improve browser page performance

1. JavaScript memory management

Basic types in stack memory that can be handled directly by the operating system; Reference types in heap memory, because they can change frequently and are not fixed in size, require JavaScript engines to handle them through garbage collection

2.Chrome memory reclamation mechanism

  1. The New generation of memory reclaim: Scavenge algorithm

  2. Old generation memory reclaiming: Mark-sweep and Mark-compact

There is a big difference between the old generation memory management and the new generation memory management. Scavenge algorithm is suitable for situations with small memory. However, when the old generation has a large memory and many variables, it is still necessary to use “mark-clear” combined with “mark-tidy” to deal with the memory problem, and try to avoid the generation of memory fragmentation

3. Memory leak and optimization

scenario

  • 1. Too many caches are not released.

  • 2. Too many closures are not released.

  • 3. Too many timers or callbacks are not released.

  • 4. Too many invalid DOM files are not released.

  • 5. Too many undiscovered global variables.

27. Talk about front-end modularization specifications

CommonJs and Es Module differences

1.CommonJs

  • CommonJs can load statements dynamically, with code occurring at run time

  • CommonJs mixed export, which is still a syntax, just doesn’t have to declare the previous object, and when I export the reference object, the previous export is overwritten

  • The CommonJs exported value is a copy. You can modify the exported value, which can cause variable contamination if the code fails

2.Es Module

  • The Es Module is static. Statements cannot be loaded dynamically. Statements can only be declared at the top of the file, and the code happens at compile time
  • Es Module mixed export, single export, default export, completely unrelated
  • Es Module exports are mapped before they are referenced, and the values are readable and cannot be modified

28. CSS div is centered horizontally and vertically, and div height is always half the width (width is optional)

    html,
      body {
        width: 100%;
        height: 100%;
      }

      .outer {
        width: 400px;
        height: 100%;
        background: blue;
        margin: 0 auto;

        display: flex;
        align-items: center;
      }

      .inner {
        position: relative;
        width: 100%;
        height: 0;
        padding-bottom: 50%;
        background: red;
      }

      .box {
        position: absolute;
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
      }

    <div class="outer">
      <div class="inner">
        <div class="box">hello</div>
      </div>
    </div>
Copy the code

The padding-bottom value, when %, is based on the inner margin as a percentage of the width of the parent element.

29. The difference between visibility and display (and opacity)

  • The visibility setting hidden will hide the element, but its location will still exist in the page document flow and will not be deleted, so it will trigger the browser rendering engine to redraw
  • The display attribute set to None will hide the element, and its position will not be preserved, triggering backflow and redraw in the browser rendering engine.
  • Opacity sets an element to transparent, but its location is also within the page’s document stream and cannot be deleted, triggering a redraw by the browser’s rendering engine

30.js script loading problem, async, defer problem

  • Use Defer if you depend on other scripts and DOM results
  • Use async if you don’t have a strong dependency on DOM and other scripts

31. A deep copy

const isComplexDataType = obj => (typeof obj === 'object' || typeof obj === 'function') && (obj ! == null) const deepClone = function (obj, Hash = new WeakMap()) {if (constructor === Date) return new Date(obj) // Return a new Date object if (constructor ===) RegExp) return new RegExp(obj) if (hash. Has (obj)) return hash. Get (obj) let if (hash AllDesc = Object. GetOwnPropertyDescriptors (obj) / / traverse incoming parameters all the key features of the let cloneObj = Object. The create (Object. GetPrototypeOf (obj), AllDesc) // Inherit the stereotype chain hash. Set (obj, cloneObj) for (let key of Reflect.ownKeys(obj)) { cloneObj[key] = (isComplexDataType(obj[key]) && typeof obj[key] ! == 'function') ? deepClone(obj[key], hash) : obj[key] } return cloneObj }Copy the code

32. What is the order in which Vue’s parent and child lifecycle hooks are executed

  • 1. Load the render process

Parent beforeCreate-> parent created-> parent beforeMount-> child beforeCreate-> child created-> child beforeMount-> Child Mounted -> parent

  • 2. Child component update process

Parent beforeUpdate-> child beforeUpdate-> child updated-> parent updated

  • 3. Update the parent component

Father father beforeUpdate – > updated

  • 4. Destruction process

Parent beforeDestroy-> child beforeDestroy-> child Destroyed -> parent Destroyed

Bottom line: From the outside to the inside, and from the inside to the outside

33. Under what circumstances does a in the following code print 1?

var a = ? ; if(a == 1 && a == 2 && a == 3){ conso.log(1); }Copy the code

Because == is implicitly cast, we can override the toString method

var a = {
  i: 1,
  toString() {
    return a.i++;
  }
}

if( a == 1 && a == 2 && a == 3 ) {
  console.log(1);
}
Copy the code

34. Look at the scope

What does the following code output

var a = 10;
(function () {
    console.log(a)
    a = 5
    console.log(window.a)
    var a = 20;
    console.log(a)
})()
Copy the code

Output: undefined -> 10 -> 20

Resolution:

Var a = 20; The statement defines a local variable a, which is promoted to the top of the body of the function that executes immediately due to js’s variable declaration promotion mechanism. Since this promotion does not include assignment, the first print statement will print undefined, and the last print statement will print 20.

Due to variable declaration promotion, a = 5; When this statement executes, the local variable a is already declared, so the effect of this statement is to assign to the local variable a, and the window. A is still assigned to 10.

35. In Vue, why can’t a child modify a Prop passed by its parent, and if so, how does Vue monitor the property changes and alert it

1. Why can’t the child component change the Prop passed by the parent component

One-way data flow, easy to monitor the flow of data, error can be more quickly to locate the location of the error occurred.

2. If yes, how does Vue monitor the property change and give a warning

if (process.env.NODE_ENV ! == 'production') { var hyphenatedKey = hyphenate(key); if (isReservedAttribute(hyphenatedKey) || config.isReservedAttr(hyphenatedKey)) { warn( ("\"" + hyphenatedKey + "\" is a  reserved attribute and cannot be used as component prop."), vm ); } defineReactive$$1(props, key, value, function () { if (! isRoot && ! isUpdatingChildComponent) { warn( "Avoid mutating a prop directly since the value will be " + "overwritten whenever the parent component re-renders. " + "Instead, use a data or computed property based on the prop's " + "value. Prop being mutated: \"" + key + "\"", vm ); }}); }Copy the code

When initProps is used, when defineReactive is used, it determines whether the key is in the development environment. If it is in the development environment, it determines whether the key was modified in the updatingChildren when the set is fired. If not, it indicates that the change was made by the child component. The warning message is displayed.

Note that the prompt is triggered when you change a prop of the underlying type from a child component. In this case, you cannot modify the parent component’s data source, because the underlying type copies the value when it is assigned. When you directly assign another non-base type (Object, array) to this key, the prompt is also triggered (but does not actually affect the parent data source). When you modify the properties of Object, the prompt is not triggered, and the data in the parent data source is changed.

36. Both cookies and tokens are stored in the header. Why not jack the token?

1, the token is not to prevent XSS, but to prevent CSRF;

2. The reason for CSRF attack is that the browser will automatically bring cookies, but the browser will not automatically bring tokens

37. What does the following code print and why

var b = 10; (function b(){ b = 20; console.log(b); }) ();Copy the code

1 The printed content is as follows:

ƒ b() {b = 20; console.log(b) }Copy the code

The reason:

Scope: The execution context contains the chain of action: Before we understand the chain of scope, let’s introduce scope. Scope can be understood as the variables declared in the execution context and the scope of the action. Includes block-level scope/function scope;

Property: declaration advance: a declaration is visible within the body of a function, and function declarations take precedence over variable declarations. In non-anonymous self-executing functions, the function variable is read-only and cannot be modified.

38. The realization Promise. Race ()

Promise._race = promises => new Promise((resolve, reject) => {
	promises.forEach(promise => {
		promise.then(resolve, reject)
	})
})
Copy the code

39. Output the result of the following code execution and explain why

var obj = {
    '2': 3,
    '3': 4,
    'length': 2,
    'splice': Array.prototype.splice,
    'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)
Copy the code

Results:

  • The push() method adds one or more elements to the end of the array and returns the new length of the array.
  • According to MDN, push method should create an attribute with subscript length for the array according to the parameter of the array length.
  • The push method affects the length attribute of the array and the value of the corresponding subscript

Add the splice property method and the length property to the object. This object becomes an array of classes.

The explanation of the title should be:

  • 1. Set obj[2]=1 by using the first push method of obj object; obj.length+=1
  • 2. Set obj[3]=2 by using the second push method of obj object; obj.length+=1
  • 3. When output using console.log, obj is printed as an array because it has the length attribute and splice method
  • 4. Since the array is not set with subscript 0 and 1, the array is printed as empty, and the active obj[0] is obtained as undefined

The first and second steps can be explained as follows: because only one parameter is passed in each push, the length of obj.length is only increased by 1. More parameters can be added to the push method itself

40. What is the difference between for in and for of

  • For in is suitable for traversing objects
  • For of is suitable for traversing the number group

For-of loops do not support normal objects, but if you want to iterate over the properties of an object, the following method can do it

For (var key of object.keys (someObject)) {console.log(key + ": "+ someObject[key]); Var obj = {a:1, b:2, c:3}; obj[Symbol.iterator] = function*(){ var keys = Object.keys(obj); for(var k of keys){ yield [k,obj[k]] } }; for(var [k,v] of obj){ console.log(k,v); }Copy the code

All objects that have a Symbol. Iterator are said to be iterable

41. Webpack packs the build process and which classes are used

  • 1. The Webpack CLI starts the packaging process.
  • 2. Load the Webpack core module and create the Compiler object.
  • 3. Use the Compiler object to start compiling the entire project;
  • 4. Parse module dependencies from the entry file to form a dependency tree.
  • 5. Recursive dependency tree, handing each module to the corresponding Loader for processing;
  • 6. Merge the results processed by Loader and output the packaged results to the dist directory.

42. Prototype chain, inheritance

43. Vue response principle? Basically ask

Link: www.bilibili.com/video/BV1G5…

44.TS related knowledge

45. Vue performance optimization

  • 1. Functional Components

    The component code before optimization is as follows:

    <template>
      <div class="cell">
        <div v-if="value" class="on"></div>
        <section v-else class="off"></section>
      </div>
    </template>
    
    <script>
    export default {
      props: ['value'],
    }
    </script>
    
    Copy the code

    The optimized component code is as follows:

    <template functional>
      <div class="cell">
        <div v-if="props.value" class="on"></div>
        <section v-else class="off"></section>
      </div>
    </template>
    
    Copy the code

    Different from ordinary object type components, functional components are not regarded as real components. As we know, in the patch process, if a node is a component Vnode, the initialization process of sub-components will be recursively executed. The functional component’s render generates a normal VNode, and there is no recursive subcomponent process, so the render overhead is much lower. So, functional components don’t have state, they don’t have responsive data, lifecycle hook functions, things like that. You can think of it as taking a part of the common component template DOM and rendering it as a function, which is a kind of reuse at the DOM level.

    1. Child component splitting

46. Array flattening (depth flattened)

47. Spa single-page application, how to avoid memory leak

Introduction to the

If you are developing with Vue, be aware of memory leaks. This is particularly important in a single-page application (SPA), where users are designed to use it without having to refresh the browser, so JavaScript applications need to clean up their own components to ensure that garbage collection works as intended.

Memory leaks in Vue applications are usually not from Vue itself, but more often occur when other libraries are integrated into the application.

A more common real-world scenario is to use the Vue Router to route to different components in a single-page application. When a user navigates through your application, the Vue Router removes elements from the virtual DOM and replaces them with new ones. Vue’s beforeDestroy() lifecycle hook is a good place to solve this type of problem in Vue Router-based applications. We can put the cleanup in the beforeDestroy() hook, like this:

beforeDestroy: function () {
  this.choicesSelect.destroy()
}
Copy the code

conclusion

Vue makes it easy to develop great responsive JavaScript applications, but you still need to be wary of memory leaks. These memory leaks tend to occur when using third-party libraries for DOM operations other than Vue. Be sure to test your application for memory leaks and do the necessary component cleanup when appropriate.

48. Principle of Solt and slot-scope in vue

The following explanations are based on Vue 2.6

  1. Slot and solt-scope are consolidated into functions within components

  2. Their rendering scope is all subcomponents

  3. And both can be accessed via this.$scopedSlots

The parent component goes through a series of initialization processes, and each slot is converted to a function corresponding to a key(slot name, or default if unnamed) (or overarguments if scoped). The child component instance this.$scopedSlots can access the ‘slot function’ in the parent component. If it’s a regular slot, call the function directly to generate VNode. If it’s a scoped slot, call the function with props to generate VNode.

Summary: Vue 2.6 has consolidated slots and slot-scope so that they are all functions. All slots can be accessed directly from this.$scopedSlots, which makes it easier to develop advanced components. In terms of optimization, Vue 2.6 also tries to keep slot updates from triggering renderings of the parent component, using a series of clever judgments and algorithms to avoid unnecessary renderings as much as possible. In version 2.5, slot generation scope is in the parent component, so child slots are updated with the parent component)

Specific article link: juejin.cn/post/684490…

49. Routing hooks in the Vue lifecycle

1. Complete route navigation resolution process (excluding other life cycles)

    1. Navigation triggered
    1. Call the beforeRouteLeave guard in the deactivated component
    1. Calls the global beforeEach guard
    1. Call the beforeRouteUpdate guard in a reused component (2.2+)
    1. Call beforeEnter in the route configuration
    1. Resolve the asynchronous routing component
    1. Call beforeRouterEnter in the activated component
    1. Call the global beforeResolve guard (2.5+)
    1. Navigation confirmed
    1. Call the afterEach hook globally
    1. Triggering A DOM update
    1. Call the callback function passed to next in the beforeRouteEnter guard, and the created component instance is passed as an argument to the callback function

2. The full sequence in which hooks are fired

The sequence in which routing navigation, keep-alive, and component lifecycle hooks are triggered, assuming the first entry from component A into component B:

  • BeforeRouteLeave: The hook before a component of a routing component leaves the route to cancel route leaving
  • BeforeEach: global front guard of routes, which can be used for login authentication and global route loadding
  • BeforeEnter: route exclusive guard
  • BeforeRouteEnter: Hook before the component of a routing component enters the route
  • BeforeResolve: Route global resolution guard
  • AfterEach: route global afterhook
  • BeforeCreate: component life cycle. This cannot be accessed
  • Created: Life cycle of a component that can access this but cannot access the DOM
  • BeforeMount: Component life cycle
  • Deactivated: Leave cache component A, or trigger a’s beforeDestroy and Destroyed component destruction hooks
  • Mounted: Accesses or operates the DOM
  • Activated: Enter the cache component and enter a’s nested subcomponent (if any)
  • Run the beforeRouterEnte callback function next

50. Life cycle? Which lifecycle can you get the real DOM? What lifecycle is triggered when you modify data in data?

  1. There are eight stages: before/after creation, before/after loading, before/after updating, before/after destroying.
  • Life cycle functions during creation
    • BeforeCreate: The instance has just been created in memory, and the data and methods properties have not been initialized

    • Created: The instance has already created OK in memory, data and methods have already created OK, and the template has not yet been compiled

    • BeforeMount: The template has been compiled at this point, but has not been mounted to the page

    • Mounted: The compiled template is mounted to the specified container on the page for display

  • Lifecycle functions during runtime:
    • BeforeUpdate: This function is executed before the status update, when the status values in the data are up to date, but the data displayed on the interface is old because the DOM node has not yet been rerendered

    • Updated: This function is called after the instance has been updated, when the status values in the data and the data displayed on the interface have been updated and the interface has been rerendered!

  • Life cycle functions during destruction:
    • BeforeDestroy: called before the instance is destroyed. At this step, the instance is still fully available.
    • Destroyed: Called after the Vue instance is destroyed. When called, everything indicated by the Vue instance is unbound, all event listeners are removed, and all child instances are destroyed.
  1. Mounted Life cycle The real DOM can be obtained

  2. Modifying data in Data triggers beforeUpdate and Updated life cycles

51. Why is Vue component data a function

When data is a function, the data attribute of each instance is independent and does not affect each other

52. Vue component communication? When you say vuex, you ask how to use vuex? What’s the difference between action and mutations? Implementation principle?

  1. props/$emit


  2. e m i t / emit/
    on

  3. vuex

      1. Vue Components: Indicates the Vue Components. HTML page, responsible for receiving user actions and other interactive behavior, execute the dispatch method to trigger the corresponding action for response
      1. Dispatch: The operation behavior triggering method. It is the only method that can execute an action
      1. Actions: Action behavior handling module, triggered by $store.dispatch(‘action name ‘, datal) in the component. Commit () then triggers the call to mutation, indirectly updating the state. Is responsible for handling all interactions received by Vue Components. Contains synchronous/asynchronous operations, supports multiple methods of the same name, and fires in the order in which they are registered. The operations requested to the background API are performed in this module, including triggering other actions and submitting mutations. This module provides encapsulation of promises to support chained triggering of actions.
      1. Commit: Indicates how to commit a state change. Submitting the mutation is the only way to execute the mutation
      1. Mutations: Method of state change operation, triggered by commit(‘mutation name ‘) in actions. Is the only recommended way for Vuex to modify state. This method can only be synchronized, and the method name must be globally unique. During the operation, some hooks will be exposed for state monitoring and so on.
      1. State: Page state management container object. The scattered data of data objects in Vue Components is stored in a centralized manner, which is globally unique for unified state management. The data required for the page display is read from this object, utilizing Vue’s fine-grained data response mechanism for efficient status updates.
      1. State object reading method
  4. $attrs/$listeners

    • $attrs: contains feature bindings (except class and style) that are not identified (and obtained) in the parent scope of a prop. When a component does not declare any prop, all parent bindings (except class and style) are included, and internal components can be passed through v-bind=”$attrs”. Usually used with the interitAttrs option.
    • $Listeners: Contains v-ON event listeners in the parent scope (without.native decorators) It can pass in internal components via V-on =”$Listeners”

In short: $listeners = Props (Props, Props, Props); $listeners = Props (Props, Props); Listeners hold non-native events bound to the parent component.

  1. provide/inject

    The new API in Vue2.2.0 requires this pair of options to be used together to allow an ancestor component to inject a dependency into all of its descendants, regardless of the component level, for as long as the upstream and downstream relationships are established. In a nutshell: the ancestor component supplies variables via a provider, and the descendant component injects variables via a inject. The Provide/Inject API mainly solves the communication problem between cross-level components, but its use scenario is that the child component obtains the state of the parent component, and the cross-level components establish a kind of active provision and dependency injection relationship.

  2. Parent /parent /parent /children and ref

53 $nextTick role? How does it work? The degradation of microtasks to macro tasks, often asked to name several macro tasks, microtasks.

$nextTick: Performs a delayed callback after the next DOM update loop ends. Use this method immediately after modifying the data to get the updated DOM.

Implementation principle:

1. Ability test

As we all know, Event Loop is divided into macro task and Micro task. No matter whether the macro task or micro task is executed, it will enter the next tick after completion and perform UI rendering between the two ticks. However, macrotasks take more time than microtasks, so use microtasks preferentially when the browser supports them. If the browser does not support microtasks, use macro tasks. However, the efficiency of macro tasks varies from one to the other, and different macro tasks need to be used depending on the browser support.

2. Execute the callback queue in different ways based on capability detection

Degrade processing: Promise -> MutationObserver -> setImmediate -> setTimeout

  • Macro task:
    • I/O, each event in the event queue is a MacroTask

    • setTimeout / setInterval

    • MessageChannel is a communication channel API supported by IE11 and above and other browsers.

    • At present, setImmediate only realizes this method in IE10 and other browsers do not support it. Function callback function supported by Node.

    • RequestAnimationFrame is also a macro task node does not support.

  • Micro tasks
    • Promise.then catch finally
    • The MutationObserver browser, which is not supported by nodes above IE11, is called when the specified DOM changes
    • Process. nextTick browser does not support Node support
[] let pending = false function nextTick (cb) {callbacks. Push (cb) if (! pending) { pending = true setTimeout(flushCallback, 0) } } function flushCallback () { pending = false let copies = callbacks.slice() callbacks.length = 0 copies.forEach(copy => { copy() }) }Copy the code

54. Vue scoped attribute? How does it work?

When the style tag has this scoped attribute, its CSS applies only to the elements of the current component

<style scoped>
.example {
 color: red;
}
</style>
<template>
 <div class="example">hi</div>
</template>

<style>
.example[data-v-5558831a] {
 color: red;
}
</style>
<template>
 <div class="example" data-v-5558831a>hi</div>
</template>
Copy the code

How it works: PostCSS adds a unique dynamic property to all the DOM in a component. Then, it adds an additional property selector to the CSS selector to select the DOM in that component. This makes the style apply only to the DOM containing that property — the internal DOM of the component

55. How many modes does the Vue Router have? Implementation?

  1. Hash pattern

Hash mode works with a HashChange event that listens for hash changes in the window. Let’s add a random #xx to the end of the URL to trigger this event.

HashHistory push and replace()

  window.onhashchange = function(event){
    console.log(event);
  }
Copy the code
  1. History mode (for HTML5History)

HTML5History. PushState () and HTML5History replaceState ()

Adding a listener to HTML5History to modify the URL in the browser address bar is executed directly in the constructor, which listens for the POPstate event in HTML5History:

constructor (router: Router, base: ? string) { window.addEventListener('popstate', e => { const current = this.current this.transitionTo(getLocation(this.base), route => { if (expectScroll) { handleScroll(router, route, current, true) } }) }) }Copy the code

56. What’s the function of key? What would Vue do without the key? It leads to Diff’s question

  1. Key is mainly used to update the virtual DOM efficiently. The principle is that vue can accurately judge whether two nodes are the same through key in the patch process, so as to avoid frequent updating of different elements, make the whole patch process more efficient, reduce DOM operation and improve performance.

  2. In addition, not setting a key can cause hidden bugs when the list is updated

  3. The key attribute is also used in vUE when overswitching elements with the same tag name. The key attribute is also used so that vue can distinguish between them, otherwise vue will only replace its internal attributes without triggering the overswitching effect.

57. The vue Diff process

58. Vue 2.x defineProperty defect? How to deal with business code inside? $set principle? How does Vue override array methods? Check to see if you actually read the source code

1. Vue 2.x defineProperty defect

  • Object. DefineProperty cannot monitor the change of array subscript, so the element added by array subscript cannot respond in real time.

  • Object.defineproperty can only hijack the properties of an Object, so you need to iterate over each Object, each property, and if the property value is an Object, you need to iterate in depth. Proxy can hijack an entire object and return a new one.

  • Cannot listen for dynamic length changes.

    For example, if arr = [1], change ARR [10] = 20 directly, so that the listener is not heard, because length is not allowed to be overwritten in the specification, while arr[0] changes directly can be heard.

  • Array method usage cannot listen to array changes, such as push

    That’s why Vue overrides these methods, right

  • Changes in data are tracked through getters/setters. Because of this tracking, there are some grammars where vue can’t check if the data has changed. For example, adding or deleting properties of an Object.

  • Unshift shift push pop splice sort Reverse

    list[0] = 4
    list.length = 0
    Copy the code

    undetectable

This.$set(this.data, “key”,value ‘)

Object. DefineProperty itself has the ability to monitor changes in array indices: Object. DefineProperty itself can monitor changes in array indices, but in Vue, you have deprecated this feature for performance/experience cost performance reasons.

2. $set principle

In the set method, the target is an array and the object is treated separately. When target is an array, the overwritten splice method is called to manually Observe.

For objects, if the key is a property of the object itself, the update is triggered by changing the value directly, otherwise the defineReactive method is called to redefine the responsive object.

3. How does Vue override array methods

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)
const methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]

/**
 * Intercept mutating methods and emit events
 */
methodsToPatch.forEach(function (method) {  
  // cache original method
  const original = arrayProto[method]
  def(arrayMethods, method, function mutator (...args) {
    const result = original.apply(this, args)
    const ob = this.__ob__
    let inserted
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    if (inserted) ob.observeArray(inserted)
    // notify change
    ob.dep.notify()
    return result
  })
})
Copy the code

Override the methods in the array, first get the array’s __ob__, its Observer object. If there is a new value, call observeArray to continue to observe the change in the new value. Then manually call notify, notify rendering watcher, and perform the update

59. Advantages and disadvantages of vue 3.0 Proxy? How to handle that VUe3 does not support IE?

  • Proxy can Proxy arrays as well as objects. You can also proxy dynamically added properties.

60.computed and watch the difference and use of the scene? Beyond the basic, see if you can tell the difference between the three watcher types

Computed: Calculates the attribute

A computed attribute is a new value derived from a known value in data. This new value will only change based on changes in known values and will not be affected by changes in other, unrelated data. The computed property is not in the data; the associated known value for the new value of the computed property is in the data. Changes in others affect me. Watch: Listens for changes in data

I’m listening for changes in the data and I’m listening for known values in the data and my changes affect other people

1. Scenarios that Watch is good at: one piece of data affects multiple pieces of data

2.computed is good at dealing with scenarios where one data is affected by multiple data

61. How to implement lazy image loading

How to tell if an image appears in the current viewport (i.e. how to tell if we can see the image)

How do I control the image loading

Scheme 1: Position calculation + Scroll event + DataSet API

  • 1. Location calculation: clientTop, offsetTop, clientHeight and scrollTop all kinds of height comparison of images

  • 2. Listen for window.scroll events

  • DataSet: DataSet <img data-src=”solo.jpg”>

    • First, set a temporary Data attribute data-src to control the use of SRC instead of data-src during loading, which can be implemented using the DataSet API

    • img.src = img.datset.src

Solution 2: getBoundingClientRect API + Scroll + DataSet API

    1. Element. GetBoundingClientRect () method returns the Element size and its position relative to the viewport
      / / clientHeight represents the height of the current viewport img getBoundingClientRect (). The top < document. DocumentElement. ClientHeightCopy the code
  • 2. Monitor window. Scroll
    1. Same as above

Scheme 3: IntersectionObserver API + DataSet API

const observer = new IntersectionObserver((changes) => { // changes: ForEach ((change) => {// intersectionRatio if (change.isintersecting) {const img = change.target img.src  = img.dataset.src observer.unobserve(img) } }) }) observer.observe(img)Copy the code

Ie does not support

Scenario 4: the LazyLoading property

<img src="shanyue.jpg" loading="lazy">
Copy the code

Almost none except Chrome

The design of the form

Look at element-UI source code form design, code repository address: github.com/glihui/guo-…

63. Finally: share the link of some knowledge points collected by yourself

  • Interview high-frequency handwritten JS code

  • A large factory face

  • Webpack covers everything from the light to the deep, so that your resume is really “familiar” (Series 1)

  • Webpack covers everything from the light to the deep, so that your resume is really “familiar” (Series 2)

  • Webpack covers everything from the shallow to the deep, so that your resume really says “familiar” (Series 3)

  • Webpack covers everything from the shallow to the deep, so that your resume is really “familiar” (Series 4)

  • Webpack covers everything from the light to the deep, making your resume truly “familiar” (Series 5)