Nowadays, the technical requirements of front-end engineers are becoming higher and higher, and the ability to use common apis can no longer meet the pace of the rapid development of front-end. Nowadays, most big and medium factories will require candidates to write the principle of common front-end API to prove your understanding of the knowledge point. Next, I will list my interview and think more important CSS part, JS part of the common handwriting principle questions!

The CSS part

Classic Flex layout

Flex layouts are now widely used on both mobile and PC, so here are a few requirements that are common in everyday projects. In the following examples, we will use the Vue project as an example

Flex layout evenly distributed after line break problem

Requirement 1: There are multiple Li’s under UL, every three Li’s are in a row, and the extra line breaks are displayed.

Obviously, most of your friends use Flex layouts, and obviously there is a problem that if Li is a multiple of 3 it will work, if not, the layout will not be satisfactory to the product manager.

display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
Copy the code

Solution:

We add li at the bottom of ul as the remainder of the total array length %3.

<li class="item" style="border: none;" v-for="(ite, idx) in list.length%3" :key="idx"></li>
Copy the code

A two-column layout

Two column layout: two columns left and right, fixed left, adaptive right

rendering

  1. The first is floating

    HTML part:

    <div class="outer outer1">
        <div class="left">1-left</div>
        <div class="right">1-right</div>
    </div>
    Copy the code

    The CSS part:

    .outer1 .left {
        width: 200px;
        float: left;
    }
    .outer1 .right {
        width: auto;
        margin-left: 200px;
    }
    Copy the code
  2. The second way is flex

    HTML part:

    <div class="outer outer2">
        <div class="left">2-left</div>
        <div class="right">2-right</div>
    </div>
    Copy the code

    The CSS part:

    .outer2 { display: flex; } .outer2 .left { flex: 0 0 200px; /* flex-grow: 0; flex-shrink:0; flex-basis:200px; */ } .outer2 .right { flex: auto; } note: flex: 00 200px is short for flex: flex-grow flex-shrink flex-basisCopy the code
  3. The third way – position

    HTML part:

    <div class="outer outer3">
       <div class="left">3-left</div>
       <div class="right">3-right</div>
    </div>
    Copy the code

    The CSS part:

    .outer3 {
       position: relative;
    }
    .outer3 .left {
       position: absolute;
       width: 200px;
    }
    .outer3 .right {
       margin-left: 200px;
    }
    Copy the code
  4. The fourth way — position again

    HTML part:

    <div class="outer outer4">
        <div class="left">4-left</div>
        <div class="right">4-right</div>
    </div>
    Copy the code

    The CSS part:

    .outer4 {
        position: relative;
    }
    .outer4 .left {
        width: 200px;
    } 
    .outer4 .right {
        position: absolute;
        top: 0;
        left: 200px;
        right: 0;
    }
    Copy the code

Three column layout

Three column layout: the middle column has adaptive width, and the sides have fixed width

rendering

  1. The first way — positioning

    HTML part:

    <div class="outer outer1">
       <div class="left">1-left</div>
       <div class="middle">1-middle</div>
       <div class="right">1-right</div>
    </div>
    Copy the code

    The CSS part:

    .outer1 { position: relative; } .outer1 .left { position: absolute; width: 100px; } .outer1 .middle { margin: 0 200px 0 100px; } .outer1 .right { position: absolute; width: 200px; top: 0; right: 0; } Note: Use absolute positioning for left and right, and set margins in the middleCopy the code
  2. The second way – Flex layout

    HTML part:

    <div class="outer outer2">
       <div class="left">2-left</div>
       <div class="middle">2-middle</div>
       <div class="right">2-right</div>
    </div>
    Copy the code

    The CSS part:

    .outer2 {
       display: flex;
    }
    .outer2 .left {
       flex: 0 0 100px;
    }
    .outer2 .middle {
       flex: auto;
    }
    .outer2 .right {
       flex: 0 0 200px;
    }
    Copy the code
  3. The third way – floating principle

    HTML part:

    <div class="outer outer3">
       <div class="left">3-left</div>
       <div class="right">3-right</div>
       <div class="middle">3-middle</div>
    </div>
    Copy the code

    The CSS part:

    .outer3 .left{
       float: left;
       width: 100px;
    }
    .outer3 .right {
       float: right;
       width: 200px;
    }
    .outer3 .middle {
       margin: 0 200px 0 100px;
    }
    Copy the code

The holy grail layout

Holy cup layout: middle priority rendering, separate left, middle and right structures

Steps to achieve the Grail layout:

  1. Let the left and right float in a row display, relative positioning
  2. Make the middle width of the middle module 100%
  3. Move the left color block to the front of middle, margin-left:-100%
  4. Move the right color block behind the middle, margin-left:- width
  5. Add an padding property padding to the parent elements of the three small blocks to squeeze the padding into the middle
  6. Move the left block to the left:-200px, move the right block to the right:-200px

rendering

HTML part:

<header>header</header>
   <div class="container">
      <div class="middle">midlle</div>
      <div class="left">left</div>
      <div class="right">right</div>
   </div>
<footer>footer</footer>
Copy the code

The CSS part:

header, footer {
   height: 100px;
   width: 100%;
   background-color: antiquewhite;
}
.container {
   height: 200px;
   padding-left: 200px;
   padding-right: 300px;
}
.container > div {
   float: left;
   position: relative;
   height: 100%;
}
.left {
   width: 200px;
   height: 200px;
   background-color: burlywood;
   margin-left: -100%;
   left: -200px;
}
.right {
   width: 300px;
   height: 200px;
   background-color: burlywood;
   margin-left: -300px;
   right: -300px;
}
.middle {
   width: 100%;
   height: 200px;
   background-color: #b0f9c2;
}
Copy the code

Twin wing layout

Twin wing layout

Specific steps to achieve the layout of twin flying wings:

  1. Float left, center and right on one line
  2. Give middle a width of 100%
  3. Make the left module move the left margin-left of the middle :-100%
  4. Make the right module move the middle’s right margin-left:- its own width
  5. Add outer spacing margin to middle container: left and right

Effect:

HTML part

<div class="main">
    <div class="middle">
			<div class="middle-inner"> middle </div> </div> <div class="left"> left </div> <div class="right"</div> </div>Copy the code

The CSS part

.main>div { 
    float:left;
    position: relative;
    height: 300px; 
}
.middle { 
    width: 100%;
    background-color: lightgreen 
}
.left { 
   width:200px;
   margin-left:-100%;
   background-color:#b0f9c2 
}
.right { 
   width: 200px;
   margin-left:-200px;
   background-color:pink 
}
.middle-inner{
   margin:0 200px; 
   background-color: burlywood; 
   height:300px;
}
Copy the code

Horizontal and vertical center

HTML part

<div class="box" id="box"Word-wrap: break-word! Important; "> < div style =" max-width: 100%;Copy the code

The CSS part

Public sector

body {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}
.box {
    box-sizing: border-box;
    width: 100px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    font-size: 16px;
    border: 1px solid lightblue;
    background: lightcyan;
}
Copy the code

The first is positioning

.box {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -50px;
    margin-top: -25px;
}
Copy the code

Note: The above method is to be sure to know the specific width and height. But the following way is to know the width and height without using the width and height.

Second: Flex

body {
    display: flex;
    justify-content: center;
    align-items: center;
}
Copy the code

Note: This approach is also not very compatible

Third: JavaScript

lethtml = document.documentElement, winW = html.clientWidth, winH = html.clientHeight, boxW = box.offsetWidth, // boxH = box. box.style.position ='absolute';
            box.style.left = (winW - boxW) / 2 + 'px';
            box.style.top = (winH - boxH) / 2 + 'px';
Copy the code

Type 4: table-cell

body {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}
Copy the code

JS part

Count the tags that appear on web pages

Implementation steps:

  1. Get all DOM nodes
  2. The NodeList collection is converted to an array
  3. Gets the label name of each element of the array
  4. duplicate removal
new Set([...document.querySelectorAll(The '*')].map(ele=>ele.tagName)).size
Copy the code

JS deep and shallow copy

Object depth copy, is one of the common interview questions.

Original object:

let obj = {
   a: 100,
   b: [100, 200, 300],
   c: {
      x: 10
   },
   d: /^\d+$/
}
Copy the code

Shallow clone

Shallow clones clone only the first layer

Method one:

letobj2 = {... obj};Copy the code

Method 2:

let obj2 = {};
for(let key in obj) {
   if(! obj.hasOwnProperty(key))break;
   obj2[key] = obj[key];
}
Copy the code

A deep clone

Note: Functions, dates, regular expressions, and json.stringify are all converted to objects {}

Method one:

let obj3 = JSON.parse(JSON.stringify(obj));
Copy the code

Method 2:

functionDeepClone (obj) {// Filter some special casesif(obj === null) return null;
    if(typeof obj ! = ="object") return obj;
    if(typeof window ! = ='undefined'&&window. JSON) {// Browsers that support window.JSON use JSONreturn JSON.parse(JSON.stringify(obj));
    }
    if(obj instanceof RegExp) {// regularreturn new RegExp(obj);
    }
    if(obj instanceof Date) {// Datereturnnew Date(obj); } / /let newObj = {}
    // let newObj = new Object()
    letnewObj = new obj.constructor; // The purpose of not creating an empty object directly: the result of cloning and the previous class = "can clone an ordinary object, but also can clone an instance objectfor(let key in obj) {
        if(obj.hasOwnProperty(key)) { newObj[key] = deepClone(obj[key]); / /}}let newObj = obj.constructor === Array ? [] : {};
    //for(let key in obj) {
    //    newObj[key] = typeof obj[key] === 'object'? deepCopy(obj[key]) : //obj[key]; / /}return newObj;
}
Copy the code

Native Ajax

A complete Ajax request generally consists of the following steps:

  • Instantiate the XMLHttpRequest object
  • Connecting to the server
  • Send the request
  • introduce
function ajax(options) {
  let method = options.method || 'GET'Params = options.params, // data = options.data, Url = options.url + (params?'? ' + Object.keys(params).map(key => key + '=' + params[key]).join('&') : ' '),
      async  = options.async === false ? false : true,
      success = options.success,
      headers = options.headers;

  letxhr; // Create an XHR objectif(window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else {
    xhr = new ActiveXObject('Microsoft.XMLHTTP');
  }

  xhr.onreadystatechange = function() {
    if(xhr.readyState === 4 && xhr.status === 200) {
      success && success(xhr.responseText);
    }
  }

  xhr.open(method, url, async);
  
  if(headers) {
    Object.keys(Headers).forEach(key => xhr.setRequestHeader(key, headers[key]))
  }

  method === 'GET' ? xhr.send() : xhr.send(data)
}
Copy the code

Note: IE5 and ie6 are not XMLHttpRequest compatible, so use the ActiveXObject() object and pass in ‘microsoft.xmlhttp’ for compatibility purposes.

  • ReadyState:

    0 – (uninitialized) The send() method has not been called

    1 – (load) The send() method has been called and the request is being sent

    2 – (load completed) The send() method is complete and all responses have been received

    3 – (Interaction) Parsing the response content

    4 – (Done) The response content is parsed and can be invoked on the client side

Anti-shake and throttling

Nowadays, the front-end interface is more and more complex, and some frequent operations may cause low page performance and user experience. For example: input box search will frequently adjust the port interface, zoom in and out of the window, etc.

When an event is continuously triggered and no event is triggered for a certain period of time, the event handler is executed once. If the event is triggered again before the specified time, the delay starts again.

const debounce = (fn, delay) => {
  let timer = null;
  return(... args) => { clearTimeout(timer); timer =setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};
Copy the code

Throttle-throttle Ensures that event handlers are invoked only once in a specified period of time when events are continuously emitted.

const throttle = (fn, delay = 500) => {
  let flag = true;
  return(... args) => {if(! flag)return;
    flag = false;
    setTimeout(() => {
      fn.apply(this, args);
      flag = true;
    }, delay);
  };
};
Copy the code

Parsing URL parameters

functionParseParam (url) {// Put the browser address in '? 'const paramsStr = /.+\? (.+)$/.exec(url)[1]; Const paramsArr = paramsstr.split (const paramsArr = paramsstr.split ('&'); // define the parsed objectletparamsObj = {}; // Run the paramsarr. forEach(param => {// Check whether there are keys and valuesif(/=/.test(param)) {// Structure gets the key and value of the objectlet [key, val] = param.split('='); // decodeURIComponent(val); Val = /^\d+$/.test(val)? parseFloat(val) : val; // Check whether there is a key attribute in the storage objectif(paramsObj. HasOwnProperty (key)) {// Store an array if it exists paramsObj[key] = []. Concat (paramsObj[key], val); }elseParamsObj [key] = val; // paramsObj[key] = val; }}else{// paramsObj[param] = in the case of no valuetrue; }})return paramsObj;
}
Copy the code
let url = 'https://www.baidu.com?username=%22tmc%22&password=%22123456%22&dutiy=%E5%89%8D%E7%AB%AF%E6%94%BB%E5%9F%8E%E7%8B%AE&flag ';
console.log(parseParam(url))

{ username: '"tmc"',
  password: '" 123456",
  dutiy: 'Front Siege Lion',
  flag: true 
}
Copy the code

The principle of the json

function jsonp({url, params, cb}) { 
   return new Promise((resolve, reject) => {
     window[cb] = function(data) {/ / declare a global variable resolve (data). The document body. RemoveChild (script)} params = {... params, cb}let arrs = []
      for(let key in params) {
         arrs.push(`${key}=${params[key]}`)}let script = document.createElement('script')
      script.src = `${url}?${arrs.join('&')}`
      document.body.appendChild(script)
   })
}
Copy the code

Disadvantages of JSONP:

  1. Only Get requests can be sent. Post, PUT, and DELETE are not supported
  2. Unsafe XSS attack

Apply the principle of

The implementation principle of Apply is similar to the implementation principle of Call, except that the parameter form is different. – the array

Function.prototype.apply = function(content = window) {
    content.fn = this;
    letresult; // Check if there is a second argumentif(arguments[1]) { result = content.fn(... arguments[1]); }else {
        result = content.fn();
    }
    delete content.fn;
    return result;
}
Copy the code

Note: When apply passes null as the first argument, this in the function body points to the window.

The principle of the bind

The bind method creates a new function. When the new function is called, the first argument to bind() will be this when it runs, and the subsequent sequence of arguments will be passed as its arguments before the arguments passed.

Function.prototype.bind = function(content) {
   if(typeof this ! ='function') {
      throw Error('not a function');
   }
   let _this = this;
   let args = [...arguments].slice(1);
   return function F() {// Determine if it is used as a constructorif(this instanceof F) {
         return _this.apply(this, args.concat([...arguments]))
      }
      return _this.apply(content, args.concat([...arguments]))
   }
}
Copy the code

The principle of the call

Call syntax: fun.call(thisArg, arg1, arg2, arg3,…..)

The core principles of Call:

  • Sets the function as a property of the object
  • Execute and delete this function
  • Execute the function by specifying this to the function and passing in the given argument
  • If no argument is passed, the default point is window
Function.prototype.call2 = function(content = window) {// Check whether underfine and null //if(typeof content === 'undefined' || typeof content === null){
    //     content = window
    // }
    content.fn = this;
    let args = [...arguments].slice(1);
    letresult = content.fn(... args); delete content.fn;return result;
}
Copy the code

Note: When call passes null as the first argument, this in the function body points to the window.

The principle of the new

How to implement a new operator:

  • First the function takes unquantified arguments. The first argument is the constructor, and the following arguments are used by the constructor
  • Then internally create an empty object obj
  • Because the obj object needs to access properties on the constructor prototype chain, we link the two through setPrototypeOf. This code is equivalent to obj.proto = con.prototype
  • Bind obj to the constructor and pass in the remaining arguments
  • Check whether the constructor returns an object. If it is, use the value returned by the constructor, otherwise use obj, thus ignoring the original value returned by the constructor
/** * create a new operator * @param {*} Con constructor * @param {... Any} args forgets the argument */ passed in the constructorfunctioncreateNew(Con, ... args) {letObj = {} // Create an object, SetPrototypeOf (obj, con.prototype) // link the Object to the constructor prototype // obj.__proto__ = con.prototype // equivalent to the aboveletResult = con.apply (obj, args) // Point this in the constructor to the object and pass the argumentreturn result instanceof Object ? result : obj
}
Copy the code

Note:

The new operator does several things:

  1. The new operator returns an object, so we need to create an object internally
  2. This object, the this in the constructor, can access any property mounted on this
  3. This object has access to properties on the constructor prototype chain, so you need to link the object to the constructor
  4. The original value should be ignored, and the returned object should be processed normally

The new operator has the following characteristics:

  1. The instance created by new through the constructor Test can access properties in the constructor as well as properties in the constructor stereotype chain, so the instance and constructor are connected by the stereotype chain through the new operator
  2. If the constructor returns the original value, the return value is meaningless
  3. If the constructor returns an object, the return value will be used normally, rendering the new operator useless

The principle of instanceof

Instanceof is used to check whether an object has a constructor’s Prototype property in its prototype chain

function instanceOf(left,right) {
    let proto = left.__proto__;
    let prototype = right.prototype
    while(true) {
        if(proto === null) return false
        if(proto === prototype) return trueproto = proto.__proto__; }}Copy the code

Promise A+ specification principle

During the advanced end of the interview. Request handwritten Promise A+ spec source code is A must. For more details, see the full version of implementing the Promise/A+ specification step by step

class Promise {
    constructor(executor) {
        this.status = 'pending'Value = undefined // The value returned after successful initialization this.reason = undefined // The cause returned after failed initialization // Resolve to handle asynchro Resolve this. OnRejectedCallbacks = [] // Reject all failed callbacks /** * @param {*} value / / Const resolve = (value) => {/ / forget -> forget -> check => {if(this.status === 'pending') {
                this.status = 'fulfilled'// This will be a big pity. Value = value // Assign the successful value to the promise // In order to solve the asynchronous resolve and return multiple promise layers This. OnResolvedCallbacks. ForEach (fn = > {fn () / / when the state into a successful state in turn perform all resolve function})}} const reject = (reason) = > {if(this.status === 'pending') {
                this.status = 'rejected'/ / fails to state transition to success failure states rejected this. A tiny = "reason / / will return to assigned to the cause of failure promise this. OnRejectedCallbacks. ForEach (fn = > {fn () / / Execute all reject})}} executor(resolve, reject) // execute the promise callback} /** * that defines the promisethenThis is a big pity. @param {*} onFulfilled fulfilled */ this is a big pitythenThis is a big pity, onRejected) {// This is a big pitythenConst promise2 = new Promise((resolve, reject) => {if(this.status === 'fulfilled'// If the state is fulfilled, the value will be passed to the successful callbacksetTimeout (() = > {const x = onFulfilled (value) this. / / the value of x for likely promise | | 123 | |'123'. // Note that no value is returned when promise2 is calledsetTimeout The simulation enters the second event loop; Let the chicken come first, let the egg come firstif(this.status === 'rejected') {
                setTimeout(() => {const x = onRejected(this.reason) // Resolve (promise2, x, resolve, promise1) reject) }, 0) }if(this.status === 'pending') {/ / record - > solve asynchronous enclosing onResolvedCallbacks. Push (() = > {setTimeout(() => {
                        const x = onFulfilled(this.value)
                        resolvePromise(promise2, x, resolve, reject) 
                    }, 0)
                })
                this.onRejectedCallbacks.push(() => {
                    setTimeout(() => {
                        const x = onRejected(this.reason)
                        resolvePromise(promise2, x, resolve, reject) 
                    }, 0)
                })
            }
        })
        returnpromise2; }} const resolvePromise = (promise2, x, resolve, reject) => {// console.log(promise2, x, resolve, reject)if(promise2 === x) {// If the value returned isthenThrow TypeError() if the method returns the same value'Circular reference'} // check if x is a promise; Note: Null typeof is also an object to excludeif(typeof x === 'function' || (typeof x === 'object'&& x ! == null)) { try { constthen= x.teng // get the return value on xthenMethods; Note that methods will report errors to catch exceptions; The reason of 111if(typeof then= = ='function'Call (x, y => {// resolve(y) // resolve(y); It is possible to return multiple nested promises resolvePromise(promise2, Y, resolve, reject)}, r => {reject(r)})} catch(e) {reject(e)}}else {
        resolve(x);
    }
}
module.exports = Promise;
Copy the code

JS array

duplicate removal

Ordinary items

let arr2 = [1, 2, 3, 2, 33, 55, 66, 3, 55];

The first:

let newArr = [];
   arr2.forEach(item => {
       if(newArr.indexOf(item) == '1') {
           newArr.push(item);
       }
   })
console.log(newArr);

// (6) [1, 2, 3, 33, 55, 66]
Copy the code

The second:

let newArr = [...new Set(arr2)];
console.log(newArr);

// (6) [1, 2, 3, 33, 55, 66]
Copy the code

Note: array.from (), filter(), for(), etc.

Object to study

let arr1 = [
    {id: 1, name: 'Tang Xiaomeng'},
    {id: 2, name: 'Shi Xiaoming'},
    {id: 3, name: 'Front-end development'},
    {id: 1, name: 'the web front end'}];Copy the code

Implementation method:

const unique = (arr, key) => {
    return [...new Map(arr.map(item => [item[key], item])).values()]
}
console.log(unique(arr1, 'id'));

// [
	{id: 1, name: "The web front end"},
	{id: 2, name: "Shi Xiaoming"},
	{id: 3, name: "Front-end development"}]Copy the code

merge

let arr3 = ['a'.'b']
let arr4 = ['c'.'d']
Copy the code

Method 1: ES5

letarr5 = arr3.concat(arr4); console.log(arr5); / / /'a'.'b'.'c'.'d']
Copy the code

Method 1: ES6

letarr6 = [...arr3, ...arr4]; console.log(arr6); / / /'a'.'b'.'c'.'d']
Copy the code

flattening

let arr7 = [1, 2, [3, 4], [5, 6, [7, 8, 9]]];
Copy the code

The first:

let arrNew = arr7.flat(Infinity);
console.log(arrNew);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
Copy the code

The second:

let arrNew = arr7.join().split(', ').map(Number);
console.log(arrNew);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
Copy the code

The third:

let arrNew = arr7.toString().split(', ').map(Number);
console.log(arrNew);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
Copy the code

Fourth:

const flattern = (arr) => {
     const result = []
     arr.forEach((item) => {
         if(Array.isArray(item)) { result.push(... flattern(item)) }else {
              result.push(item)
         }
    })
    return result
}
flattern(arr7);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
Copy the code

Fifth:

function flatten(arr) {
    return[].concat( ... arr.map(x => Array.isArray(x) ? flatten(x) : x) ) } flattern(arr7); // (1) [1, 2, 3, 4, 5, 6, 7, 8, 9]Copy the code

Array or not

let arr = []
Copy the code

First: instanceof

console.log(arr instanceof Array)
Copy the code

B) constructor

console.log(arr.constructor === Array)
Copy the code

Third: some method for determining whether an object has an array such as push

console.log(!! arr.push && !! arr.concat)Copy the code

The fourth type: toString

console.log(Object.prototype.toString.call(arr) === '[object Array]')
Copy the code

Fifth: array. isArray

console.log(Array.isArray(arr))
Copy the code

Note: the fifth way is the best ~

Bubble sort

let arr = [1, 44, 6, 77, 3, 7, 99, 12];
Copy the code
  • The principle of bubble sort algorithm is as follows:
  1. Compare two adjacent elements, and if the first is larger than the last, swap places
  2. The last element should be the largest in the first round
  3. Repeat this step for all elements except the last one
function bubbleSort(arr) {
    for(let i=0; i<arr.length; i++) {
        for(let j=0; j<arr.length - i - 1; j++) {
            if(arr[j+1] < arr[j]) {
                lettemp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; }}}returnarr; } console.log(bubbleSort(arr)); // [1, 3, 6, 7, 12, 44, 77, 99]Copy the code

Note: The last element is not compared.

Quick sort

let arr = [1, 44, 6, 77, 3, 7, 99, 12];
Copy the code
  • The principles of quicksort algorithm are as follows:
  1. Find the benchmark (usually based on the middle term)
  2. Iterate over groups of numbers, leaving those less than the baseline at left and those greater than the baseline at right
  3. recursive
function quickSort(arr) {
    if(arr.length <= 1) return arr;
    let mid = Math.floor(arr.length / 2);
    let midItem = arr.splice(mid, 1)[0];
    let leftArr = [];
    let rightArr = [];
    for(let i=0; i<arr.length; i++) {
        let current = arr[i];
        if(current >= midItem) {
            rightArr.push(current);
        } else{ leftArr.push(current); }}returnquickSort(leftArr).concat([midItem], quickSort(rightArr)); } console.log(quickSort(arr)); // [1, 3, 6, 7, 12, 44, 77, 99]Copy the code

conclusion

Summary above I interview or interview others common CSS, JS part of the handwriting principle. Hope to have friends need to think carefully read, there will be harvest. Hope you get a satisfactory offer~❤️

The last

If this article has helped you, give it a thumbs up ❤️❤️❤️

Welcome to join us to learn the front end and make progress together!