前端手写篇之防抖、节流、call、apply、instanceof、New和Object.create

81 阅读2分钟

防抖

//immediate 用来判断是否需要首次点击马上执行
          function debounce(func, wait,immediate) {
            // 缓存一个定时器id
            let timer = null
            return function () {
              let context = this
              let args = arguments
              const callNow=!timer
              if (timer) {
                clearTimeout(timer)
              }
              if(immediate){
                timer = setTimeout(() => {
                timer=null
                }, wait);
                if (callNow) func.apply(context, args)
              }
              else{
              timer = setTimeout(() => {
                func.apply(context, args)
              }, wait);
            }
          }
          }

节流

      function throttle(func,wait){
        let lastTime=0
        return function(...args){
          let now =new Date()
          if(now-lastTime>wait){
            lastTime=now
            func.apply(this,...args)
          }
        }
      }

call

    Function.prototype.myCall=function(context=window,...args){
          // 在context上加一个唯一值不影响context上的属性
          let key=Symbol('key')
          console.log('this:',this)
          //这里的this为调用myCall的这个函数
           // context为调用的上下文,this此处为函数,将这个函数作为context的方法
          context[key]=this
          let result=context[key](...args)
          delete context[key]
          return result
    }
        function f(a, b) {
            console.log(a + b)
            console.log(this.name)
          }

          let obj = {
              name: 1
            }
          console.log(f.myCall(obj, 1, 2) )

apply

      Function.prototype.myApply=function(content=window,args){   //这里传参与call进行区别
            let key=Symbol('key')
            content[key]=this
            let result=content[key](...args) 
            delete content[key]
            return result
        }

        function f(a, b) {
            console.log(a)
            console.log(b)
            console.log(this.name)
          }
          let obj = {
            name: '张三'
          }
        console.log( f.myApply(obj, [1, 2]) ) 

instanceof

    //用于检测构造函数b的 prototype 属性是否出现在a的原型链上。
    function myinstanceof(a,b){
        let test =Object.getPrototypeOf(a)
        while(true){
          if(test==null) {
            return false
          }
          if(test ===b.prototype ){
            return true
          }
          test=Object.getPrototypeOf(test)
        }
    }
    let a=new Object()
    console.log(a)
    console.log(this.myinstanceof(a,Object))

New

    //new操作符做了这些事:
     /*  创建一个全新的对象
      这个对象的__proto__要指向构造函数的原型prototype
      执行构造函数,使用 call / apply 改变 this 的指向
      返回值为object类型则作为new方法的返回值返回,否则返回上述全新对象 */
      function myNew(fn,...args){
          let instance=Object.create(fn.prototype)
          let res=fn.apply(instance,args)
          return typeof res==='object'?res:instance
      }

      function Car(make, model, year) {
          this.make = make;
          this.model = model;
          this.year = year;
        }

        const car1 = myNew( Car,'Eagle', 'Talon TSi', 1993);
          console.log(car1);

Objective.create()

 /*  Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的 __proto__ */
      function myCreate(test){
            function F() { }
            F.prototype = test;
            return new F()
      }

     const person = {
        isHuman: false,
        printIntroduction: function () {
          console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
        }
      };

      const me = myCreate(person);
      const ms = Object.create(person);

      console.log(me)
      console.log(ms)