js手写

385 阅读1分钟

1.防抖

const input1 = document.getElementById('input1')

function debounce(fn,delay = 500){
    //timer是闭包中的,被隐藏不会被外面拿到
    let timer = null;
    return function(){
        if(timer){
            clearTimeout(timer)
        }
        timer = setTimeout( () => {
            //debounce 可能会传入参数 
            //fn(),不能使用箭头函数
            //确保上下文环境为当前的this
            fn.apply(this,arguments)
            timer = null
        },delay)
    }
}

input1.addEventListener('keyup',debounce( function(){
    console.log(input1.value)
},1000 ))

2.节流


const div1 = document.getElementById('div1')

function throttle(fn,delay = 1000){
    let timer = null;
    return function (){
        if(timer){
            return
        }
        timer = setTimeout(() =>{
            //传递参数,例如此处的e
            fn.apply(this,arguments)
            timer = null
        },delay )
    }
}

div1.addEventListener('drag',throttle(function(e){
    console.log(e.offsetX,e.offsetY)
}))
  1. 深拷贝
function deepClone(obj = {}){
    if(typeof obj !== 'object' || obj == null){
        //obj是null,或者不是对象和数组,直接返回
        return obj;
    }
    //初始化返回结果
    let result ;
    if(obj instanceof Array){
        result = [];

    }else{
        result = {}
    }

    for(let key in obj){
        //保证不是原型的属性
        if(obj.hasOwnProperty(key)){
            //递归调用
            result[key] = deepClone(obj[key])
        }
    }
    //返回结果
    return result;
}
  1. 实现一个instanceOf
function instanceOf(left,right) {

    let proto = left.__proto__;
    let prototype = right.prototype
    while(true) {
        if(proto === null) return false
        if(proto === prototype) return true
        proto = proto.__proto__;
    }
}
  1. new
// objectFactory(name, 'cxk', '18')
function objectFactory() {
  const obj = new Object();
  const Constructor = [].shift.call(arguments);

  obj.__proto__ = Constructor.prototype;

  const ret = Constructor.apply(obj, arguments);

  return typeof ret === "object" ? ret : obj;
}

揭开使用new获得构造函数实例 的真相 5. bind

//模拟bind
Function.prototype.bind1 = function(){
    //将参数拆解为数组,arguments是列表,不是数组
    const args = Array.prototype.slice.call(arguments)

    //获取this (数组第一项)
    const t = args.shift();
    

    //fn1.bind(...)中的fn1,bind是返回一个函数
    const self = this;

    // bind 是 返回一个函数
    return function(){
        //apply第一个参数是this,第二个参数是数组
        return self.apply(t,args)
    }
}