用原生js实现一个bind方法

bind用法介绍:

bind()方法建立一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供以前提供一个给定的参数序列。

这段是来自MDN:bind的介绍,咱们能够理解bind方法返回一个新的函数,这个函数内部的this指向提供的参数值,来看个例子react

const person = {
      age: 20,
      getAge() {
        return this.age
      }
    }
  const getAge = person.getAge
  console.log(getAge()) // output :undefined

上面代码输出了undefined,什么缘由呢?相信你们都知道,getAge()执行时内部的this指向了window,而window并无age这个属性,咱们并无定义全局的age变量,那咱们怎么解决这个问题呢?那就是用哪一个bind方法,须要注意的是bind方法的兼容性,IE9以上包括IE9。其余现代浏览器不用说确定是支持的。下面咱们用一下bind方法来修改上面的例子面试

const person = {
      age: 20,
      getAge() {
        return this.age
      }
    }
  const getAge = person.getAge.bind(person)
  console.log(getAge()) // output :20

咱们看到经过bind方法就能够输出age了数组

bind语法格式

fun.bind(thisArg[, arg1[, arg2[, ...]]])

参数

thisArg浏览器

当绑定函数被调用时,该参数会做为原函数运行时的 this 指向。当使用new 操做符调用绑定函数时,该参数无效。

arg1, arg2, ...app

当绑定函数被调用时,这些参数将置于实参以前传递给被绑定的方法

返回值

返回由指定的this值和初始化参数改造的原函数拷贝

我的理解:bind方法接受的第一个参数是你想绑定的this值,一般是个对象,这个对象在函数内部用this能够获取到,第一个参数后面能够跟若干个参数,这些参数能够在bind的时候传递,至关于预设参数。函数

好了,知道用法和参数后咱们就能够实现一个简陋版的了oop

Function.prototype.bind=function (context) {
  if(typeof this !=='function'){
    throw new Error(`${this.name} is not a function`)
  }
  const srcFun=this// 保存原始函数
  const arg=Array.prototype.slice.call(arguments,1)// 把arguments类数组转为真实数组
  let noop=function(){}
  const fBound= function () {
   if(this instanceof noop){
     context=this
   }
    // 合并新旧参数
    return srcFun.apply(context,arg.concat(Array.prototype.slice.call(arguments,0)))
  }
  if(this.prototype){
    noop.prototype=this.prototype//维护原型关系,指向原始函数
  }
  fBound.prototype=new noop()//新函数的prototype的__proto__指向noop.prototype
  return fBound
}

很简陋,没有严谨的判断。学习

一个绑定函数也能使用new操做符建立对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。

上面是MDN的一段话,也就是bind返回的函数也能够当作构造函数来用,此时bind传递的第一个参数无效,可是其余参数有效。this

那么要作判断处理就是prototype

//代码2
if(this instanceof noop){
     context=this
   }

这段代码就能够区分出是在把函数当作构造函数来new了仍是当作普通方法来调用了,咱们知道
当new 的时候实际作了这点事

var obj={}
obj._proto_=构造函数的prototype
构造函数.call(obj)

因此如今在代码2中的this是构造函数的实例,那就得更改bind后的函数,让bind后的fBound函数的prototype指向noop的实例,这样此时的this就借助noop实例指向了noop的原型,那么this instanceof noop就是true了

总结

上面是我对bind方法的一些理解和实现,仅供参考和学习。bind方法在react中会比较经常使用到,有些面试题也会让本身实现一个,因此尝试一下也能学到很多东西了。

相关文章
相关标签/搜索