Fwio

prototype 函数中的 this 绑定

在重做山月前端面试基础中 bind 一题时,由于对this理解不到位,写出如下错误答案

Function.prototype.myBind = (obj) => {
  return (...args) => this.apply(obj, args)
}

function f(arg) {
  console.log(this.a, arg)
}

// TypeError: this.apply is not a function
f.myBind({ a: 2 })(4)

error: TypeError 通常表示对变量进行了不合理的操作

其中,返回的箭头函数并没有问题,但myBind不能使用箭头函数定义,因为返回函数的this继承自外层的myBind, 由于myBind也用箭头函数定义,那么在定义时this静态地指向了Global对象,Global不是一个函数,不存在apply属性,所以报错。

将外层的myBind改为常规函数(function () {})的写法即可:

Function.prototype.myBind = function (obj) {
  return (...args) => this.apply(obj, args)
}

function f(arg) {
  console.log(this.a, arg)
}

// 2, 4
f.myBind({ a: 2 })(4)

这样,所返回箭头函数的this将由myBind()运行时确定,也正好就是实例化的函数对象