class类 与 react类组件的bind(this)

在 react 的类组件中,如果我们需要某个点击事件,通常会这样写: onClick={this.changeWeather}
但为了能够使 changeWeather 方法中能够正确找到 this, 我们通常需要在constructor构造器中这样写:this.study = this.study.bind(this)

为了能够比较好地解释清楚这个原理,我们先来回顾一下 es6 的 class:

es6的class类 :

  class Person {

    // new Person()后,constructor构造器中的属性在实例对象上
    constructor(name, age) {
      this.name = name
      this.age = age
    }

    // 方法在原型上
    speak () {
      this.study()
    }

    // 方法在原型上
    study () {
      console.log('study', this)
    }
  }

  var p1 = new Person('tom', 18).study
  console.log(p1)
  p1() // window调用study方法,所以结果为:undefined (类中开启局部严格模式,所以不指向window)

  var p2 = new Person('alice', 23)
  p2.study() // Person的实例对象调用study方法,所以结果为:Person {name: 'alice', age: 23}

只有通过Person实例对象调用study方法时,this才会指向Person

为了能够使 p1() 也能够通过this找到Person实例对象,就需要在 constructor 添加 this.study = this.study.bind(this):

    constructor(name, age) {
      this.name = name
      this.age = age
      
      // bind(this)中, this指的就是Person实例对象
      this.study = this.study.bind(this)
    }

构造器中的this指向的是:实例对象

分两步:
1.  = 右边相当于先找到原型中的方法study, 然后改变原型中study的this指向(指到实例对象上);
2.  = 左边相当于将改变完this指向的函数体给到 属性 study, 使得实例对象上也有study方法。


添加前:Person {name: 'alice', age: 23}  -- study 方法在原型上;
添加后:Person {name: 'alice', age: 23, study: ƒ} -- study 方法在Person实例对象


这样,由于实例对象自身有study,就不去原型上去找study方法来,所以此时 var p1 = new Person('tom', 18).study 的study就是改变完this指向的。
 

react的类组件:

  // var VDOM = <div>hello react!</div>
  // ReactDOM.render(VDOM, document.getElementById('app'))


  // function VDOM () {
  //   return (
  //     <div>hello react!!</div>
  //   )
  // }
  // ReactDOM.render(<VDOM />, document.getElementById('app'))
  

  class VDOM extends React.Component {
    constructor() {
      super()
      this.state = { isHot: false }
      // 将changeWeather方法的this指向VDOM实例(=右边), 并在该实例对象上添加changeWeather方法(=左侧),
      this.changeWeather = this.changeWeather.bind(this)
    }

    render () {
      return (
        // onClick={this.changeWeather} 代表直接把函数体给了click事件,
        //  相当于:var x = new VDOM().changeWeather; x();
        <div onClick={this.changeWeather}>{ this.state.isHot ? '1'  : '2' }</div>
      )
    }
 
    changeWeather () {
      console.log(33, this)
    }
  }

  
  

  ReactDOM.render(<VDOM />, document.getElementById('app'))

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值