11. bind的实现 - cw84973570/Learning-notes GitHub Wiki

https://github.com/mqyqingfeng/Blog/issues/12

思路:

用apply改变函数的this 当返回的函数作为构造函数时将this指向new出来的对象

还不是很熟练,下次再默写下

用apply实现最简单的版本

Function.prototype.bind2 = function (context) {
  var self = this
  return function () {
    return self.apply(context)
  }
}

传递参数

Function.prototype.bind3 = function (context) {
  var self = this
  var arr1 = Array.prototype.slice.call(arguments, 1)
  return function () {
    var arr2 = Array.prototype.slice.call(arguments, 1)
    return self.apply(context, arr1.concat(arr2))
  }
}

使用new操作符时将this指向生成的对象

Function.prototype.bind4 = function (context) {
  var self = this
  var arr1 = Array.prototype.slice.call(arguments, 1)
  var boundFun = function () {
    var arr2 = Array.prototype.slice.call(arguments, 1)
    // 当用new操作符时this指向构造函数的实例,也就是this是boundFun的一个实例
    return self.apply(this instanceof boundFun ? this : context, arr1.concat(arr2))
  }
  // 这里修改fBound的prototype时,也会修改原函数的prototype
  // 绑定函数的prototype修改为原函数的prototype,这样就能继承原函数原型中的属性
  boundFun.prototype = self.prototype
  return boundFun
}

中转prototype

Function.prototype.bind5 = function (context) {
  var self = this
  var arr1 = Array.prototype.slice.call(arguments, 1)
  var boundFun = function () {
    var arr2 = Array.prototype.slice.call(arguments, 1)
    // 当用new操作符时this指向构造函数的实例,也就是this是fBound的一个实例
    return self.apply(this instanceof boundFun ? this : context, arr1.concat(arr2))
  }
  // 用一个空对象来当绑定函数的prototype,即原型,这样在修改prototype时就不会影响到原函数的prototype
  var middleFun = function () {}
  middleFun.prototype = self.prototype
  boundFun.prototype = new middleFun()
  return boundFun
}