# bind的实现原理

bind通过闭包缓存this

# bind的用法

我们通常使用Function.prototype.bind解决this指向问题,通过bind我们可以获得一个新的函数,这个函数中的this指向为我们指定的那个对象。

function f() {
  console.log(this.name)
}

const person = {
  name: 'zhuli',
}

const newFunc = f.bind(person)

console.log(newFunc === f) // false
f() // undefined
newFunc() // zhuli

# bind通过闭包实现代理和缓存

bind返回一个新的函数,这个函数在调用时this永远指向绑定的对象,那么疑问是:

this只存在于调用时产生的执行上下文,怎么能提前指定呢?

bind的实现原理如下:

Function.prototype._bind = function (scope) {
  const fn = this
  return function () {
    return fn.apply(scope, arguments)
  }
}

function f() {
  console.log(this.name)
}

const person = {
  name: 'zhuli',
}

const newFunc = f._bind(person)

f() // undefined
newFunc() // zhuli

bind的核心实现是通过闭包实现对原函数的代理执行,通过将scope上下文对象和fn原函数缓存在自由变量中,保证不论什么时候访问函数都可以获得指定的this

# React中bind的绑定

class Dialog extends React.Component {
  constructor(props) {
    super(props)
    // 这里通过bind绑定this到方法中
    // 返回的方法实际是对原方法的代理:return function() {return fn.apply(xxx)}
    this.handleClick = this.handleClick.bind(this)
  }
	
  // 类语法中没有箭头函数的定义,这里定义的都是普通函数
  // 类似Dialog.prototype.handleClick = function () {}
  // 现在有试验性的语法:handleClick = () => {},提前绑定this
  // 猜测这种语法也类似上面的bind操作
  handleClick() {
    console.log(this)
  }

  render() {
    // 由于render方法被Dialog对象调用,所以这里也可以改成:
    // onClick={() => this.handleClick()}
    // 由于箭头函数本身没有this,所以会通过静态作用域回到定义处按照作用域链向上寻找
    return (
      <div>
        <button onClick={this.handleClick}>按钮</button>
      </div>
    )
  }
}

ReactDom.render(<Dialog></Dialog>, document.getElementById('root'))
上次更新: 2/13/2025, 3:29:47 AM