debounce/throttle

Debounce is executed only once when the event is continuously triggered for a period of time

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

When you throttle continuously triggers events for a period of time, you execute only the first time

function throttle(fn, delay = 1000){
    let flag = true
    return function(. args){
        if(flag){
            flag = false
            setTimeout(() = > {
                flag = true
            }, delay)
        }
    }
}

Copy the code

call/apply/bind

All three can change the this orientation of a function at runtime

The call () method calls a function with a specified this value and one or more arguments given separately.

function call(context, ... args){
    const ctx = context || window
    const func = Symbol()
    ctx[func] = this
    constres = ctx[func](... args)delete ctx[func]
    return res
}

Copy the code

The apply() method takes an array (or array-like) argument that specifies this

function apply(context, ... args){
    const ctx = context || window
    const func = Symbol()
    ctx[func] = this
    constres = ctx[func](... args)delete ctx[func]
    return res
}

Copy the code

The bind() method creates a new function, and when bind is called, this of the new function is specified as the first argument to bind, with the remaining arguments as arguments to the new function.

function bind(context, ... args){
    const fn = this
    return function(. newArgs){ fn.call(context, ... args, ... newArgs) } }Copy the code

new

The new keyword performs the following operations

  • Create an empty simple JavaScript object (that is {})
  • Link this object (setting its constructor) to another object
  • Use the newly created object as the this context
  • Return this if the function returns no value
function myNew(ctor, ... args){
    // Create a new object
    const obj = Object.create()
    // Link the object
    obj.prototype = ctor.prototype
    // Set the context
    constres = ctor.call(obj, ... args)/ / return
    return res instanceof Object? res: obj
    
}

Copy the code

instanceOf

The instanceOf operator is used to check whether the constructor’s prototype appears on an instance’s prototype chain

// use object instanceof constructor
function C(){}
function D(){}
const cExp = new C()
const dExp = new D()
// true because object.getProtoTypeof (cExp) === c.protoType
cExp instanceof C 
// false d.protoType is not in the cExp prototype

Copy the code
/ / implementation
function myInstanceof(Obj = instance, Cla= class){
    let leftPro = Object.getPrototypeOf(obj)
    const rightPro = Cla.prototype
    while(true) {if(! leftPro) trunfalse
        if(leftPro === rightPro) return true
        leftPro = Object.getPrototypeOf(leftPro)
    }
}

Copy the code

Object.create

The object.create () method creates a new Object, using an existing Object to provide the __proto__ of the new Object

function myCreate(ctor){
    function C(){}
    C.prototype = ctor
    return new C()
}

Copy the code

Object.assign

The object.assign () method is used to assign all enumerable attributes from one or more source objects to the target Object, which it returns

function myAssign(target, args){
    const to = Object(target)
    for(let i = 1; i< args.length; i++){
        const nextSource = args[i]
        for(let nextKey in nextSource){
            if(Object.prototype.hasOwnProperty(nextSource,nextKey)){
                to[nextKey] = nextSource[nextKey]
            }
        }
    }
}

Copy the code

deepClone

function deepClone(target){
    if(target instanceOf RegExp) return new RegExp(target)
    if(target instanceOf Date) return new Date(target)
    if(target ! = =null || typeoftarget ! = ='object') return target
    let ctor = new target.constructor()
    for(let key in target){
        if(target.hasOwnProperty()key){
           ctor = deepClone(target[key])
        }
    }
    return ctor
}
Copy the code

Array flattening

function myFlat(data){
    return Array.reduce((prev,cur) = > {
        return prev.concat(myFlat(cur))
    },[])
}

Copy the code

Node traversal

function traverse(node, nodeList = []){
    nodeList.push(node)
    const children = node.children
    for(let i = 0; i < children.length; i++){
        traverse(children[i], nodeList)
    }
    return nodeList
}

function traverse2(node){
    let nodeList = []
    nodeList.push(node)
    const children = node.children
    for(let i = 0; i < children.length; i++){ nodeList = nodeList.concat(traverse2(children[i])) }return nodeList
}

function traverse3(node){
    let nodeList = []
    let stack = []
    stack.push(node)
    while(stack.length){
        const item = stack.pop()
        nodeList.push(item)
        const children = item.children
        for(let i = 0; i< children.length; i++){
            stack.push(children[i])
        }
    }
    return nodeList
}

function traverse4(node){
    let nodeList = []
    let stack = []
    stack.push(node)
    while(stack.length){
        const item = stack.shift()
        const children = item.children
        for(let i = 0; i < children.length; i++){
            stack.push(children[i])
        }
    }
    return nodeList
}

Copy the code

The function is currified

function sum(a, b, c){
    return a + b + c
}
const sum = curry(sum)
sum(1) (2) (3) / / 6
function curry(fn, ... args){
    const fnLen = fn.length
    const argsLen = args.length
    // If there are not enough arguments, return curry
    // Execute the function if there are enough arguments
    if(fnLen > argsLen){
        return function(. args2){
            returncurry(fn, ... args,... args2) } }else{ fn(... args) } }Copy the code

JSONP

function JSONP(url, data){
    const callback = 'callback' + Math.random()
    const src = url + '? callback=' + callback
    const script = document.createElement('script')
    script.setAttribute('type'.'text/javascript')
    script.src = src
    return new Promise((resolve, reject) = > {
        window[callback] = r= > {
          resolve(r)
          headEle.removeChild(JSONP)
          delete window[callback]
        }
        headEle.appendChild(JSONP)
    })
}
JSONP().then(res= > {
    // Res is the data we want to get
    console.log(res)
})
Copy the code

Observer model

Defines a one-to-many dependency between objects in which all dependent objects are notified and automatically updated when an object’s state changes

class Subject{
    constructor(){
        this.name = 'JavaScript'
        this.observers = []
    }
    attach(obs){
        this.observers.push(obs)
    }
    detach(obs){
        this.observers.remove(obs)
    }
    notify(){
        this.observers.forEach(o= > o.update(this.name))
    }
}
class Observer{
    update(){
        console.log('Received notification of update')}}const sub = new Subject()
const obsmm = new Observer()
const obsnn = new Observer()
sub.attach(obsmm)
sub.attach(obsnn)
sub.notify()
Copy the code

EventEmitter event listener

class EventEmitter{
    constructor(){
        this.events = {}
    }
    on(event, cb){
        const cbList = this.events[event] || []
        cbList.push(cb)
        this.events[event] = cbList
    }
    off(event, cb){
        const cbList = this.events[event] || []
        this.events[event] = cbList.filter(fn= >fn ! == cb)return this
    }
    emit(event, ... args){
        const cbList = this.events[event] || []
        cbList.forEach(fn= >fn(... args))return this
    }
    this.once(event, cb){
        const fn = function(. args){ cb(... args)this.off(event, fn)
        }
        this.on(event, fn)
    }
}
Copy the code

Sort arrays randomly/generate random numbers

let arr = [2.3.454.34.324.32]
arr.sort(randomSort)
function randomSort(a,b){
    return Math.random() > 0.5? -1: 1
}
// --------------------------------------
function getRandom(max, min){
    return Math.random() * (max - min) + min
}

Copy the code

sleep

The sleep function puts the thread to sleep until it wakes up again at a specified time

function sleep(delay){
    const start = new Date().getTime()
    while(new Date().getTime() - start < delay){
        continue}}function test(){
    console.log('start')
    sleep(2000)
    console.log('end')
}
test()
Copy the code

Object array decrement

// Convert value to a string using set
const arr = [{a:1.b:2.c:3}, {b:2.c:3.a:1}, {d:2.c:2}]
objSort(obj){
    let newObj = Object.create({})
    Object.keys(obj).forEach(key= > {
        newObj[key] = obj[key]
    })
    return JSON.stringify(newObj)
}
function unique(arr){
    let set = new Set(a)for(let i = 0; i < arr.length; i++){
        set.add(objSort(arr[i]))
    }
    returm [...set].map(item= > JSON.parse(item))
}

Copy the code

Promise

let id = 0
const PENDING = 0
const FULFILLED = 1
const REJECTED  = 2
class Promise{
    constructor(excutor){
        this.promiseId = ++id
        this.state = undefined
        this.result = undefined
        this.subscribers = []
        excutor(function resolvePromise(value){
            this.resolve(value)
        }, function rejectPromise(reason){
            this.reject(reason)
        })
    }
    resolve(value){
        if(this.state ! == PENDING)return 
        this.state = FULFILLED
        this.result = value
        // This is a big pity. // This is a big pity. // This is a big pity.
        if(this.subscribers.length){
            this.publish
        }
    },
    reject(reason){
        if(this.state ! == PENDING)return
        this.state = REJECTED
        this.result = reason
    }
    then(onFulfilled,onRejected){
        const child = new Promise(function(){})
        State has a value for resolve or reject if the task is synchronized
        // The then callback needs to be executed and the new PROMISE assigned
        If an asynchronous task executes resolve or reject, then callbacks are collected
        if(this.state){
            this.invokeCallback(this.state,child,onFulfilled,this.result)
        }else{
            this.subscribe(child,onFulfilled,onRejected)
        }
    }
    subscribe(promise, onFulfilled,onRejected){
        const length = this.subsceibers.length
        this.subscribers[length] = promise
        this.subscribers[length + FULFILLED] = onFulfilled
        this.subscribers[length + REJECTED] = onRejected
    }
    invokeCallback(state, promise, callback, result){
        let value = result
        if(getType(callback) === 'function'){
            value = callback()
        }
        // Assign a value to the newly generated promise
        promise.resolve(value)
    }
    publish(){
        for(let i=0; i<this.subscribers.length; i++){let child=this.subsctibers[i]
            let cb = this.subscribers[i + this.state]
            if(child){
                this.invokeCallback(this.state,child,cb,this.result)
            }else{
                cb(this.result)
            }
        }
    }
    
}
function getType(target){
    return Object.prototype.toString.call(target).slice(8, -1).toLowercase()
}

Copy the code