原生js手写题每日总结

50 阅读3分钟

防抖

防抖是指把频繁触发的事件合并成一次去执行,在一定时间内只执行一次回调函数,若在一段时间内多次触发,则回调函数的执行时间按最后一次触发的时间重新计算

function debounce(fun,wait=1000){
    let timer=0;
    return function(...args){
        if(timer) clearTimeout(timer)
        timer=setTimeout(()=>{
            fun.apply(this,args)
        },wait)
    }
}

使用场景: input 输入触发事件;按钮提交

节流

节流是指一段时间内只能执行一个回调函数,即事件按照一定的时间间隔来进行触发。若频繁出发事件,且触发事件的时间间隔小于指定的时间,则回调函数不会执行

function throttle(fun,delay=1000){
    let timer=0;
    return function(...args){
        if(timer) return;
        timer=setTimeout(()=>{
            fun.apply(this,args)
            timer=0
        },delay)
    }
}

使用场景: resize , scroll ,动画,拖拽

防抖和节流的区别

防抖是将多次执行变为最后一次执行,节流是将多次执行变成隔一段时间执行

instanceof

这个方法 Object.getPrototypeOf(o) 获取实例 o 的原型,即 o.proto

function _instanceof(instance,classO){
    if(typrof instance !== "object" || instance == null) return false;
    let proto=Object.getPrototypeOf(instance)
    while(proto){
        if(proto==classO.prototype) return true;
        proto=Object.getPrototypeOf(proto)
    }
    return false;
}

new 操作符

new 操作符是调用一个构造函数来创建一个新对象

new操作符的内部步骤:

  1. 创建一个新的空对象,空对象的原型__proto__指向构造函数的原型prototype
  2. 构造函数的上下文this的指向为新对象,执行构造函数,得到构造函数的返回值
  3. 若返回值为对象,则返回值作为new方法的返回值返回,否则,返回新创建的对象
function _new(contructor,...args){
    //obj.__proto__=constructor.prototype
    const obj=Object.create(constructor.prototypre);
    let res=constructor.apply(obj,args)
    return typeof res=="object"?res:obj;
}

Object.create()

Object.create()方法:原型式继承,根据指定对象o1为原型创建新对象o2,即o2.__proto__===o1

function createObj(o1){
    function Fun(){}
    Fun.prototype=o
    // o2 = new Fun() : o2.__proto__ = Fun.prototype=o1
    return new Fun()
}
const o1={...}
const o2=createObj(o1)

call

call 方法是改变函数的上下文后调用函数,call 方法的第一个参数是 this 的指向,剩下的参数是函数的参数,返回值为函数调用返回的值

注:若没有参数, this 指向 window ;若 this 指向的不是对象,则调用 new Object()方法将其转为对象

call() 方法做了:

  1. 将函数作为某个对象的方法属性,则当用此对象调用函数时,函数的上下文this就指向了此对象
  2. 调用对象的函数方法,得到函数的返回值
  3. 删除对象的此方法,防止污染
  4. 返回返回值

因为 call 方法是所有函数的方法,所以,他是 Function 原型上的方法

Function.prototype._call=function(context=window,...args){
    if(typeof context !=="object") context=new Object(context)
    // 创建一个唯一值,作为context的属性名不会被覆盖
    let fnKey=Symbol()
    context[fnKey]=this
    let res=context[fnKey](...args)
    delete context[fnKey]
    return res;
}

apply

apply和call基本相同,只是传给函数的参数必须是一个数组

Function.prototype._apply=function(context=window,args){
    if(typeof context !=="object") context=new Object(context)
    let fnKey=Symbol()
    context[fnKey]=this
    let res=context[fnKey](...args)
    delete context[fnKey]
    return res;
}