“This article has participated in the call for good writing activities, click to view: the back end, the big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!”

“Do you understand how XXX works? “Can you use your own ideas to achieve XXX?” This article aims to use their own ideas to achieve some functions, I hope you have some help.

The map method of an array

The map method of an array creates a new array. The result is that each element in the array is the return value of a call to the provided function.

Array.prototype.map = function(fn){
  let result = []
  for(let i; i<this.length; i++){
    if(i in this){
        result.push(fn(this[i], i, this))}}return result
}
Copy the code

Promise

class Promise {
  constructor(executor) {
    // Initialize the status to pending
    this.state = 'pending'
    // Success value
    this.value = undefined
    // Cause of failure
    this.reason = undefined
    // Successfully stored array
    this.onResolvedCallbacks = []
    // Failed to store the array
    this.onRejectedCallbacks = []

    let resolve = value= > {
      if (this.state === 'pending') {
        // The state will change to depressing after the call is successful
        this.state = 'fulfilled'
        // Save the successful value
        this.value = value
        // Once resolve is executed, the function of the success array is called
        this.onResolvedCallbacks.forEach(fn= > fn())
      }
    }

    let reject = reason= > {
      if (this.state === 'pending') {
        // reject, the state changes to Rejected
        this.state = 'rejected'
        // Cause of storage failure
        this.reason = reason
        // Once r eject executes, call the function of the failed array
        this.onRejectedCallbacks.forEach(fn= > fn())
      }
    }

    try {
      executor(resolve, reject)
    } catch (err) {
      reject(err)
    }
  }

  then(onFulfilled, onRejected) {
    if (this.state === 'fulfilled') {
      onFulfilled(this.value)
    }
    if (this.state === 'rejected') {
      onRejected(this.reason)
    }
    // When the status is pending
    if (this.state === 'pending') {
      // Ondepressing's value is passed into the success array
      this.onResolvedCallbacks.push(() = > {
        onFulfilled(this.value)
      })
      // The value of onRejected is passed into the failure array
      this.onRejectedCallbacks.push(() = > {
        onRejected(this.reason)
      })
    }
  }
}
Copy the code

Deep copy

function deepClone(obj, hash = new WeakMap(a)) {
  if (obj instanceof RegExp) return new RegExp(obj)
  if (obj instanceof Date) return new Date(obj)
  if (obj === null || typeofobj ! = ='object') {
    return obj
  }
  if (hash.has(obj)) {
    return hash.get(obj)
  }
  let t = new obj.constructor()
  hash.set(obj, t)
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      t[key] = deepClone(obj[key], hash)
    }
  }
  return t
}
Copy the code

call/apply

Function.prototype.call = function() {
    let [thisArg, ...args] = [...arguments];
    if(! thisArg) {// Context is null or undefined
        thisArg = typeof window= = ='undefined' ? global : window;
    }
    // This refers to the current function func (func.call)
    thisArg.func = this;
    // Execute the function
    letresult = thisArg.func(... args);delete thisArg.func; ThisArg does not have a func attribute, so it needs to be removed
    return result;
}

Function.prototype.apply = function(thisArg, rest) {
    let result; // The function returns the result
    if(! thisArg) {// Context is null or undefined
        thisArg = typeof window= = ='undefined' ? global : window;
    }
    // This refers to the current function func (func.call)
    thisArg.func = this;
    if(! rest) {// The second argument is null/undefined
        result = thisArg.func();
    }else{ result = thisArg.func(... rest); }delete thisArg.func; ThisArg does not have a func attribute, so it needs to be removed
    return result;
}
Copy the code

Anti-shake/throttling

// throttling (execute once for a period of time, then do not execute again)
function throttle(fn, delay) {
  let canUse = true
  return function() {
    if (canUse) {
      fn.apply(this.arguments)
      canUse = false
      setTimeout(() = > (canUse = true), delay)
    }
  }
}

const throttled = throttle(() = > console.log('hi'))
throttled()

// Do it together.
function debounce(fn, delay) {
  let timerId = null
  return function() {
    const context = this
    if (timerId) {
      window.clearTimeout(timerId)
    }
    timerId = setTimeout(() = > {
      fn.apply(context, arguments)
      timerId = null
    }, delay)
  }
}
const debounced = debounce(() = > console.log('hi'))
debounced()
Copy the code

AJAX

var request = new XMLHttpRequest()
request.open('GET'.'/a/b/c'.true)
request.onreadystatechange = function() {
  if (request.readyState === 4 && request.status === 200) {
    console.log(request.responseText)
  }
}
request.send('name=abc&age=20')
Copy the code

EventHub was finally implemented with TS

class EventHub {
  private cache: { [key: string]: Array<(data: unknown) = > void>} = {}on(eventName: string, fn: (data: unknown) => void) {
    this.cache[eventName] = this.cache[eventName] || []
    this.cache[eventName].push(fn)
  }
  emit(eventName: string, data? : unknown){(this.cache[eventName] || []).forEach(fn= > fn(data))
  }

  off(eventName: string, fn: (data: unknown) => void) {
    this.cache[eventName] = this.cache[eventName] || []
    let index = indexOf(this.cache[eventName], fn)
    if (index === -1) return
    this.cache[eventName].splice(index, 1)}}export default EventHub;

/** * help function indexOf *@param arr 
 * @param item 
 */
function indexOf(arr, item) {
  if (arr === undefined) return -1
  let index = -1
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === item) {
      index = i
      break}}return index
}
Copy the code

One last word

If this article is helpful to you, or inspired by the words, help like attention, your support is the biggest motivation I insist on writing, thank you for your support.