我们已经知道在JS中:ES5的this是谁调用就指向谁,箭头函数的this是在哪里定义就指向谁

下面看看三种React组件中的this是什么,并且为什么会这样。

  1. function定义的函数组件
  2. const定义的函数组件
  3. Class组件

普通函数组件 fucntion () {}

  1. function ThisTest () {
  2. console.log('this', this)
  3. return (
  4. <div>Hello, ThisTest</div>
  5. )
  6. }
  7. // this undefined

JS module中自动使用strict模式,故依然是undefiend,而非global

  • Also, note that you might get different behavior from sections of script defined inside modules as opposed to in standard scripts. This is because modules use strict mode automatically.

—-MDN-JavaScript modules

  1. <script>
  2. console.log('script1', this) // Window
  3. </script>
  4. <script type="module">
  5. console.log('script2', this) // undefined
  6. </script>

箭头函数组件 const

  1. import React from 'react'
  2. console.log('Module this:', this)
  3. const ThisTest = () => {
  4. console.log('ThisTest this:', this)
  5. return (
  6. <div>Hello, ThisTest</div>
  7. )
  8. }
  9. // Module this: undefined
  10. // ThisTest this: undefined

因为箭头函数定义在js模块中,而顶层js模块的的this就是undefined。在组件外输出this依然为undefined。

当然,函数组件并不需要使用this,真正有使用场景的还是class组件。

class组件

我们知道class组件的函数有两种绑定this至组件的方法:

  1. // 1: bind绑定this
  2. constructor (props) {
  3. super(props)
  4. this.handleClick = this.handleClick.bind(this)
  5. }
  6. // 2: 使用箭头函数
  7. handleClick = () => { /.../ }

若不绑定,函数里的this会指向undefined。

  1. class ThisTest extends React.Component {
  2. handleClick () {
  3. console.log('click', this)
  4. }
  5. render () {
  6. return (
  7. <div onClick={this.handleClick}>Hello, ThisTest</div>
  8. )
  9. }
  10. }

但为什么是undefined呢?onClick={this.handleClick}会作为React合成事件转换成addEventlistener,但是addEventListener的回调函数里的this不是指向绑定函数的DOM元素吗?

1.当我们查看React-dom有关合成事件的源码,就可知(TODO!)
this.handleClick不是作为addEventListener的回调函数,而是回调函数的一部分。在回调里调用的函数即为匿名函数的调用,会指向global。

  1. const h = function () {
  2. console.log('bbbbbbbb', this) // Window
  3. }
  4. document.getElementById('root').addEventListener('click', function () {
  5. console.log('cccccccc', this) // <div></div>
  6. h()
  7. })

2.综上那this.handleClick会指向global吗?并没有,handleClick是class里定义的函数。Class内部定义会使用strict模式,所以handleClick则指向undefined。

The body of a class is executed in strict mode, ——MDN - Classes