Great oaks from little acorns grow on a solid foundation to remain invincible forever. Here are 10 common JavaScript handwriting features, with comments added where important. Some refer to others, some write their own, if there are incorrect places, welcome to correct.

1, the image stabilization

function debounce(fn, delay) {
  let timer
  return function (. args) {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() = > {
      fn.apply(this, args)
    }, delay)
  }
}

/ / test
const task = () = > {
  console.log('run task')}const debounceTask = debounce(task, 1000)
window.addEventListener('scroll', debounceTask)
Copy the code

2, throttle

function throttle(fn, delay) {
  let last = 0 // Last trigger time
  return (. args) = > {
    const now = Date.now()
    if (now - last > delay) {
      last = now
      fn.apply(this, args)
    }
  }
}

/ / test
const task = () = > {
  console.log('run task')}const throttleTask = throttle(task, 1000)
window.addEventListener('scroll', throttleTask)
Copy the code

3. Deep copy

function deepClone(obj, cache = new WeakMap(a)) {
  if (typeofobj ! = ='object') return obj // Common type, return directly
  if (obj === null) return obj
  if (cache.get(obj)) return cache.get(obj) // Prevent loop references, the program into an infinite loop
  if (obj instanceof Date) return new Date(obj)
  if (obj instanceof RegExp) return new RegExp(obj)
  
  // Find the constructor of the owning prototype, which points to the constructor of the current object
  let cloneObj = new obj.constructor()
  cache.set(obj, cloneObj) // Cache the copied object to handle cyclic references
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      cloneObj[key] = deepClone(obj[key], cache) // Recursive copy}}return cloneObj
}

/ / test
const obj = { name: 'Jack'.address: { x: 100.y: 200 } }
obj.a = obj // Circular reference
const newObj = deepClone(obj)
console.log(newObj.address === obj.address) // false
Copy the code

4. Fulfill promises

class MyPromise {
  constructor(executor) { // executor executor
    this.status = 'pending' // Wait state
    this.value = null // Parameters for success or failure
    this.fulfilledCallbacks = [] // Successful function queue
    this.rejectedCallbacks = [] // Failed function queue
    const that = this
    function resolve(value) { // The method of success
      if (that.status === 'pending') {
        that.status = 'resolved'
        that.value = value
        that.fulfilledCallbacks.forEach(myFn= > myFn(that.value)) // Execute the callback method}}function reject(value) { // Fail method
      if (that.status === 'pending') {
        that.status = 'rejected'
        that.value = value
        that.rejectedCallbacks.forEach(myFn= > myFn(that.value)) // Execute the callback method}}try {
      executor(resolve, reject)
    } catch (err) {
      reject(err)
    }
  }
  then(onFulfilled, onRejected) {
    if (this.status === 'pending') {
      // Wait state, add callback function to successful function queue
      this.fulfilledCallbacks.push(() = > {
        onFulfilled(this.value)
      })
      // Add the callback function to the failed function queue
      this.rejectedCallbacks.push(() = > {
        onRejected(this.value)
      })
    }
    if (this.status === 'resolved') { // Support synchronous invocation
      console.log('this'.this)
      onFulfilled(this.value)
    }
    if (this.status === 'rejected') { // Support synchronous invocation
      onRejected(this.value)
    }
  }
}

/ / test
function fn() {
  return new MyPromise((resolve, reject) = > {
    setTimeout(() = > {
      if(Math.random() > 0.6) {
        resolve(1)}else {
        reject(2)}},1000)
  })
}
fn().then(
  res= > {
    console.log('res', res) // res 1
  },
  err= > {
    console.log('err', err) // err 2
  })
Copy the code

5, asynchronous control concurrency

function limitRequest(urls = [], limit = 5) {
  return new Promise((resolve, reject) = > {
    const len = urls.length
    let count = 0 // The number of tasks currently in progress

    const start = async() = > {const url = urls.shift() // Get the first task from the array
      if (url) {
        try {
          await axios.post(url)
          if (count == len - 1) {
            // Last task
            resolve()
          } else {
            count++
            // Successful, start the next task
            start()
          }
        } catch (e) {
          count++
          // Fail to start the next task
          start()
        }
      }
    }

    // Start the limit task
    while (limit > 0) {
      start()
      limit -= 1}})}/ / test
limitRequest(['http://xxa'.'http://xxb'.'http://xxc'.'http://xxd'.'http://xxe'])
Copy the code

6. ES5 Inheritance (Combined Inheritance)

function Parent(name) {
  this.name = name
}
Parent.prototype.eat = function () {
  console.log(this.name + ' is eating')}function Child(name, age) {
  Parent.call(this, name) // Constructor inheritance
  this.age = age
}
Child.prototype = new Parent() // Prototype chain inheritance
Child.prototype.contructor = Child
Child.prototype.study = function () {
  console.log(this.name + ' is studying')}/ / test
let child = new Child('xiaoming'.16)
console.log(child.name) // xiaoming
child.eat() // xiaoming is eating
child.study() // xiaoming is studying
Copy the code

7, array sort

The sort order

// Sort the numbers, short
const arr = [3.2.4.1.5]
arr.sort((a, b) = > a - b)
console.log(arr) // [1, 2, 3, 4, 5]

// Sort the letters
const arr = ['b'.'c'.'a'.'e'.'d']
arr.sort((a, b) = > {
  if (a > b) return 1
  else if (a < b) return -1
  else return 0
})
console.log(arr) // ['a', 'b', 'c', 'd', 'e']
Copy the code

Bubble sort

function bubbleSort(arr) {
  let len = arr.length
  for (let i = 0; i < len - 1; i++) {
    // Start with the first element and compare two adjacent elements
    for (let j = 0; j < len - 1 - i; j++) {
      if (arr[j] > arr[j + 1]) {
        let num = arr[j]
        arr[j] = arr[j + 1]
        arr[j + 1] = num
      }
    }
    // At the end of each iteration, a maximum value is found at the end of the array
  }
  return arr
}

/ / test
console.log(bubbleSort([2.3.1.5.4])) // [1, 2, 3, 4, 5]
Copy the code

8, array deduplication

Set to heavy

cosnt newArr = [...new Set(arr)] 
Copy the code

Array. The from to heavy

const newArr = Array.from(new Set(arr))
Copy the code

IndexOf to heavy

function resetArr(arr) {
  let res = []
  arr.forEach(item= > {
    if (res.indexOf(item) === -1) {
      res.push(item)
    }
  })
  return res
}

/ / test
const arr = [1.1.2.3.3]
console.log(resetArr(arr)) / / [1, 2, 3]
Copy the code

9. Get URL parameters

function getParams(url) {
  const res = {}
  if (url.includes('? ')) {
    const str = url.split('? ') [1]
    const arr = str.split('&')
    arr.forEach(item= > {
      const key = item.split('=') [0]
      const val = item.split('=') [1]
      res[key] = decodeURIComponent(val) / / decoding})}return res
}

/ / test
const user = getParams('http://www.baidu.com?user=%E9%98%BF%E9%A3%9E&age=16')
console.log(user) // {user: 'alfy ', age: '16'}
Copy the code

10, event bus | release a subscription model

class EventEmitter {
  constructor() {
    this.cache = {}
  }

  on(name, fn) {
    if (this.cache[name]) {
      this.cache[name].push(fn)
    } else {
      this.cache[name] = [fn]
    }
  }

  off(name, fn) {
    const tasks = this.cache[name]
    if (tasks) {
      const index = tasks.findIndex((f) = > f === fn || f.callback === fn)
      if (index >= 0) {
        tasks.splice(index, 1)}}}emit(name, once = false) {
    if (this.cache[name]) {
      // Create a copy. If the same event continues to be registered within the callback function, an infinite loop will occur
      const tasks = this.cache[name].slice()
      for (let fn of tasks) {
        fn();
      }
      if (once) {
        delete this.cache[name]
      }
    }
  }
}

/ / test
const eventBus = new EventEmitter()
const task1 = () = > { console.log('task1'); }
const task2 = () = > { console.log('task2'); }

eventBus.on('task', task1)
eventBus.on('task', task2)
eventBus.off('task', task1)
setTimeout(() = > {
  eventBus.emit('task') // task2
}, 1000)
Copy the code

These are the most common handwriting functions in work or job hunting. Have you mastered all of them? Welcome to communicate in the comments section. Don’t forget to give the article a thumbs up if it helps you!

I heard that the people who like are not bad luck, I believe that next year’s first promotion will be you ~😃