• 手写bind函数


    实现bind函数

    参考MDN提供的Polyfill方案

    Function.prototype.myBind = function(context){
      //这里对调用者做一个判断,如果不是函数类型,直接抛异常
      if(typeof this !== 'function'){
        throw '调用必须为函数'
      }
      //当我们调用bind函数时,我们可能传了不只一个参数
      //如 fun.bind({}, arg1, arg2)
      //我们需要把后面的参数拿出来
      let args = Array.prototype.slice.call(arguments, 1);
      let fToBind = this; 
      let fNOP = function(){};
      let fBound = function(){
        return fToBind.apply(this instanceof fNOP ? this : context, args.concat(arguments));
      }
      if(this.prototype){
        fNOP.prototype = this.prototype;
      }
    
      fBound.prototype = new fNOP();
    
      return fBound;
    }

    fBound函数这里有个判断 this instanceof FNOP 这个其实是为了避免一种情况,因为bind函数返回的是一个函数,当我们把这个函数实例化(就是new fun())

    根据官方文档 当返回的函数被实例化的时候,this指向会锁定指向该实例,不管我们传入的参数指定this指向。

    在下面我们 返回的fBound函数时 继承一个空函数 FNOP, 当返回的函数被实例化之后,this instanceof fNOP 结果为true,从而指定this指向

    function a (){}
    function b (){}
    
    a.prototype = new b();
    
    //如果我们返回的函数实例化了  
    let c = new a();
    c instanceof b //true
    //但是大多数情况我们都是
    a instanceof b // false

    如果这里明白了,那后面的就简单了,context 参数就是我们手动指定的this指向, 当我们绑定bind时会传递多个参数,执行的时候也会带参数,我们就需要把bind

    函数除掉第一个以外的参数和我们调用方式时的参数进行拼接

    function foo (){}
    //示例中 args 就是指的[arg1, arg2]
    //args.concat(arguments) 就是将所有的arg1,arg2...arg4的参数进行拼接
    let newFoo = foo.bind({}, arg1, arg2);
    newFoo(arg3, arg4);

    另外 arguments 参数不要搞混淆了,上面那个获取的是bind时的参数(就是{}, arg1, arg2

    下面的arguments 参数是指的调用时的 (就是 arg3, arg4)

  • 相关阅读:
    02-线性结构2 一元多项式的乘法与加法运算
    两个堆栈实现列队
    队列的顺序存储和链式存储实现
    包含MIN函数的栈+一个数组实现两个堆栈+两个数组实现MIN栈
    利用纯java捕获和播放音频
    许令波老师的java的IO机制分析文章
    soundtouch源码分析__based on csdn :
    java桌面项目打包_by icewee_写得太棒了,直接转载了
    白化检验( 白噪声准则检验 )
    对于冯嘉礼老师定性映射理论的复习
  • 原文地址:https://www.cnblogs.com/wangziye/p/11318934.html
Copyright © 2020-2023  润新知