1. Handwritten call method

var obj = { name: 456, }; function say() { console.log(this.name); } Function.prototype.myCall = function (context, ... The args) {/ / defines the current the called method in CXT. Func. (this) in order to be in the form of the object binding / / to build a unique Symbol variables to avoid repetition and let CTX = context | | window; let func = Symbol(); ctx[func] = this; args = args ? args : []; // Call func as an object call, in which case this refers to CXT, which is passed in to bind this to const res = args.length > 0? ctx[func](... args) : ctx[func](); Delete CTX [func]; return res; }; say.myCall(obj); / / 456Copy the code

2. Hand write the Apply method

var obj = { name: 456, }; function say(args) { console.log(this.name); } Function.prototype.myApply = function (context, args = []) { let ctx = context || window; let func = Symbol(); ctx[func] = this; const res = args.length > 0 ? ctx[func](args) : ctx[func](); delete ctx[func]; return res; }; say.myApply(obj); / / 456Copy the code

3. Write a bind

Implementation method:

  • The bind method does not execute immediately and needs to return a function to be executed;
  • The implementation applies to the bind Apply
  • When used as a constructor, stereotype inheritance is performed
Function.prototype.myBind = function (context, ... args) { let fn = this; args = args ? args : []; return function newFunc(... args2) { return fn.apply(context, [...args, ...args2]); }; };Copy the code

4. Implement new

  • Create a new object
  • Point this to this object
  • Return this object
// Constructor function Parent() {this.name = "colin"; } function myNew(Parent, ... // create a new Object based on constructor prototype let newObj = object.create (Parent. Prototype); Let retrunResult = parent. apply(newObj, args); let isObject = typeof retrunResult === "object" && retrunResult ! ==null; let isFunction = typeof ctorReturnResult === "function"; if (isObject || isFunction) { return retrunResult; } return newObj; } let p = myNew(Parent); console.log(p.name); //colinCopy the code

5. Instanceof

  • Implement instanceof to determine if a is an instanceof a, a instanceof a, return true, otherwise return false
  • The instanceof operator tests whether an object has a constructor’s Prototype property in its prototype chain
  • Iterate through the prototype chain of the variable on the left until the prototype of the variable on the right is found, and return false if none is found
function myInstanceOf(a, b) { let left = a.__proto__; let right = b.prototype; while (true) { if (left === null) { return false; } if (left === right) { return true; } left = left.__proto__; } } let p = new Parent(); console.log(myInstanceOf(p, Parent)); //trueCopy the code

6. Handwriting function debounce

This mode applies to scenarios such as click events, which can be triggered multiple times in a row and take effect only once

function debounce(fn, time) { let timer = null; return (... args) => { clearTimeout(timer); timer = setTimeout(() => { fn(... args); }, time); }; }Copy the code

Handwriting function throttle

Applicable to continuous rolling scenarios, such as continuous triggering, every N time takes effect once

function throttle(fn, time) { let flag = true; return (... args) => { if (flag) { flag = false; setTimeout(() => { flag = true; fn(... args); }, time); }}; }Copy the code

8. Implement deep copy

  • Determine the type, re, and date to return the new object directly
  • Consider circular references and determine if the hash contains a value that returns directly from the hash
  • An empty or non-object type that returns the original value
  • Add a new corresponding new obJ. Construction to the hash
  • Traversal object recursion
function deepClone(obj, hash = new WeakMap()) { if (obj instanceof RegExp) return new RegExp(obj); if (obj instanceof Date) return new Date(obj); if (obj === null || typeof obj ! == "object") return obj; If (hash. Has (obj)) {return hash. Get (obj); } let newObj = new obj.construction(); hash.set(obj, newObj); for (let key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = deepClone(obj[key], hash); }} / / consider the symbol of the let symbolObj = Object. GetOwnPropertySymbols (obj); for (let i = 0; i < symbolObj.length; i++) { if (obj.hasOwnProperty(symbolObj[i])) { constr[symbolObj[i]] = deepClone(obj[symbolObj[i]], hash); } } return newObj; }Copy the code

9. Array flattening

Let arr = [1, 2 [3, 4]]; Function flat(arr) {return arr. Reduce ((prev, cur) => { return prev.contact(Array.isArray(cur) ? flat(cur) : cur); } []); }Copy the code

10. Function Kerritization implementation

function curry() { let _args = Array.from(arguments); var _adder = function () { _args.push(... arguments); return _adder; }; // Use the toString implicit conversion feature, when the last execution of the implicit conversion, ToString = function () {return _args.reduce(function (a, b) {return a + b; }); }; return _adder; } console.log(curry(1, 2)(4)); / / 7Copy the code

11. Random generation

  function getRandom(min, max) {
      return Math.floor(Math.random() * (max - min)) + min;
    }
Copy the code

12. Array is out of order

let arr = [2, 3, 454, 34, 324, 32]; arr.sort(randomSort); Function randomSort(a, b) {return Math. Random () > 0.5? 1:1; }Copy the code

13. Object array deduplication

  • Write a function that sorts the keys in an object and converts them to a string
  • An traversal array uses a Set to erase the object after a string
Input: [{2, a: 1, b: c: 3}, {2, b: c: 3, a: 1}, {2, d: c: 2}] output: [{2, a: 1, b: c: 3}, {d: 2, c: 2}]Copy the code
function objSort(obj) {
  let newObj = {};
  Object.keys(obj)
    .sort()
    .map((key) => {
      newObj[key] = obj[key];
    });
  return JSON.stringify(newObj);
}

function unique(arr) {
  let set = new Set();

  for (let i = 0; i < arr.length; i++) {
    let str = objSort(arr[i]);
    set.add(str);
  }
  arr = [...set].map((item) => {
    return JSON.parse(item);
  });
  return arr;
}
Copy the code

14. Template engine implementation

  • Define templates, data
Let the template = "< div > I am {{name}} < / div >, age {{age}}, {{sex}}" gender; Let data = {name: "Colin ", age: 18, sex:" male ",};Copy the code
  • Method 1:
function render(template, data) { const reg = /\{\{(\w+)\}\}/; If (reg.test(template)) {const name = reg.exec(template)[1]; // If (reg.test(template)) {const name = reg.exec(template)[1]; Replace (reg, data[name]); // Replace (reg, data[name]); // return render(template, data); // Render recursively and return the rendered structure} return template; } if the template does not have a template stringCopy the code
  • Method 2:
function render(template, data) {
 let computed = template.replace(/\{\{(\w+)\}\}/g, function (match, key){
   return data[key];
 });
 return computed;
}
Copy the code
  • Print template:
console.log(render(template, data)); //<div> I am Colin </div>, age 18, gender maleCopy the code

15. Use setTimeOut to implement setInterval (with clear timer)

function setIntervals(fn, t) { let timer = null; function interval() { fn(); timer = setTimeout(interval, t); } interval(); return { cancle: () => { clearTimeout(timer); }}; } let timeObj = setIntervals(() => { console.log(6); }, 1000); / / timeObj cancle () / / clearCopy the code

16. Implement setTimeOut with setInterval

   function mySetTimeOut(fn, t) {
      let timer = setInterval(() => {
        clearInterval(timer);
        fn();
      }, t);
    }
    
  mySetTimeOut(() => {
  console.log(9);
}, 3000);

Copy the code

17. Bubble sort

  • Time complexity n^2
function bubbleSort(arr) { let len = arr.length; Var I = 0; var I = 0; i < len; I++) {// the inner loop is used to repeat the comparison during each round of the loop + swap for (var j = 0; j < len - 1; j++) { let temp; if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return arr; } console.log(bubbleSort([2, 1, 6, 4, 3])); // [1, 2, 3, 4, 6]Copy the code

quicksort

  • Time complexity n^2
function selectSort(arr) { let len = arr.length; // cache the current interval minimum index let minIndex; For (var I = 0; i < len - 1; MinIndex = I; minIndex = I; minIndex = I; minIndex = I; minIndex = I; for (var j = i; j < len; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } if (minIndex ! == i) { let temp; temp = arr[minIndex]; arr[minIndex] = arr[i]; arr[i] = temp; } } return arr; } console.log(selectSort([2, 1, 6, 4, 3])); / /,2,3,4,6 [1]Copy the code

quicksort

function quickSort(arr) { if (arr.length < 2) { return arr; } let current = arr[arr.length - 1]; let left = arr.filter((itm, idx) => itm <= current && idx ! == arr.length- 1); let right = arr.filter((itm, idx) => itm > current); return [...quickSort(left), current, ...quickSort(right)]; } console.log(quickSort([2, 1, 6, 4, 3])); / /,2,3,4,6 [1]Copy the code

Class arrays are converted to array methods

Array.from array. from(arrayLike) // 3.Array.prototype. Slice Array.prototype.slice.call(arrayLike) // 4.Array.apply Array.apply(null, arrayLike) // 5.Array.prototype.concat Array.prototype.concat.apply([], arrayLike)Copy the code

21. The Object is realized

Object.js does not convert the type of the two values being compared, similar to ===, but different:

  • NAN is different in === and equal in object. is
  • +0 and -0 are equal at === and unequal at object.js
Function (a, b) {if (a === b) {if (a == b) {if (a == b) { 1/+0 ===Infinity 1/-0=== -infinity return a! == 0 || 1 / a === 1 / b; } //a! If ==b, there is one way that they are equal: a and B are NaN return a! == a && b ! == b; }; console.log(Object.is(+0, -0)); //false console.log(Object.is(NaN, NaN)); //trueCopy the code

22. Implement setInterval using requestAnimationFrame

  • Advantages: requestAnimationFrame comes with a throttling function, which ensures that the delay is accurate and only executed once in 16.6 milliseconds.
function setInterval(callback, interval) { let timer; const now = Date.now; let startTime = now(); let endTime = startTime; const loop = () => { timer = window.requestAnimationFrame(loop); endTime = now(); if (endTime - startTime >= interval) { startTime = endTime = now(); callback(timer); }}; timer = window.requestAnimationFrame(loop); return timer; }Copy the code
let a=0 setInterval((timer) => { console.log(1); a++; If (a==4){cancelAnimationFrame(timer)// Cancel timer}}, 1000);Copy the code