如何理解React组件中的this

在读这篇文字之前建议先理解JavaScript中作用域链的概念,戳这里:JavaScript中的执行环境、作用域链和闭包详解,以及理解JavaScript中的this关键字,戳这里:JavaScript中的this关键字如何理解
原生的JavaScript中只有对象,没有类的概念。其对象是基于原型链实现的。
如果要生成一个对象实例,需要先定义一个构造函数,然后通过new操作符来完成。构造函数示例:

//函数名和实例化构造名相同且大写
function Person(name,age) {
    this.name = name;
    this.age=age;
}
Person.prototype.say = function(){
    return "我的名字叫" + this.name+"今年"+this.age+"岁了";
}
var obj=new Person("laotie",88);//通过构造函数创建对象,必须使用new 运算符
console.log(obj.say());//我的名字叫laotie今年88岁了

构造函数生成实例的执行过程:

  1. 当使用了构造函数,并且new 构造函数(),后台会隐式执行new Object()创建对象;
  2. 将构造函数的作用域给新对象,(即new Object()创建出的对象),而函数体内的this就代表new Object()出来的对象。
  3. 执行构造函数的代码。
  4. 返回新对象(后台直接返回);
    ES6引入了Class(类)这个关键词,使得JavaScript的对象更像面向对象的语言,但实际上class定义的依旧是函数(typeof 输出的是function类型)。
    改写之前的代码:
class Person{//定义了一个名字为Person的类
	//constructor是一个构造方法,用来接收初始化参数,通过new命令生成对象实例时,自动调用该方法。
    constructor(name,age){ 
        this.name = name;//this代表的是实例对象
        this.age=age;
    }
    say(){//这是一个类的方法,注意千万不要加上function
        return "我的名字叫" + this.name+"今年"+this.age+"岁了";
    }
}
var obj=new Person("laotie",88);
console.log(obj.say());//我的名字叫laotie今年88岁了

React 组件

现在来看React菜鸟教程中的React 组件这一节。这就明白了为什么可以通过这两种方式定义组件。
在这里插入图片描述

React 组件中的this关键字

在React菜鸟教程React 事件处理这一节,有这样一段代码:
在这里插入图片描述
为了更方便理解this这个关键字,以React菜鸟教程React 表单与事件这一节中的一个实例为例:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 实例</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="example"></div>

<script type="text/babel">
class Content extends React.Component {
  render() {
    return  <div>
            <input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp} /> 
            <h4>{this.props.myDataProp}</h4>
            </div>;
  }
}
class HelloMessage extends React.Component {
  constructor(props) {
      super(props);
      this.state = {value: 'Hello Runoob!'};
      this.handleChange = this.handleChange.bind(this);
  }
 
  handleChange(event) {
    this.setState({value: event.target.value});
  }
  render() {
    var value = this.state.value;
    return <div>
            <Content myDataProp = {value} 
              updateStateProp = {this.handleChange}></Content>
           </div>;
  }
}
ReactDOM.render(
  <HelloMessage />,
  document.getElementById('example')
);
</script>

</body>
</html>

现在改写script代码如下(就是打印了一些值出来):

class Content extends React.Component {
    render() {
        return  <div>
            <input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp}/>
            <h4>{this.props.myDataProp}</h4>
        </div>
    }
}
class HelloMessage extends React.Component {
    constructor(props) {
        super(props);
        console.log(`In HelloMessage---------`);
        console.log(this);
        console.log(typeof this);
        console.log(typeof HelloMessage);
        console.log(this.handleChange);
        console.log(typeof this.handleChange);
        console.log(`End HelloMessage---------`);
        this.state = {value: 'hello Runoob!'};
        // this.handleChange();
        // this.handleChange = this.handleChange.bind(this);

    }
    handleChange(event) {
        console.log("In handleChange------------");
        console.log(typeof this);
        console.log(this);
        console.log("End handleChange------------");

        // this.setState({value:event.target.value});
    }
    render() {
        var value = this.state.value;
        return <div>
            <Content myDataProp = {value}
                updateStateProp = {this.handleChange}>
            </Content>
        </div>
    }
}

console.log(`%%%%%%%%%%%%%%%%%%%%%%%%%%${typeof HelloMessage}`);
ReactDOM.render(
    <HelloMessage />,
    document.getElementById('example')
);

结果如下,可以得出结论:HelloMessage是函数,this关键词指向函数所在的当前对象,也就是this把HelloMessage当做对象来看待,可以调用HelloMessage中定义的函数。
在这里插入图片描述
现在在输入框中输入字符(没有显示),但是可以调用到在Content中为输入框定义的onChange事件,结果如下,说明handleChange中的this并没有指向某个对象,handleChange只是作为一个普通的函数,this值为undefined。
在这里插入图片描述
现在把构造函数中的this.handleChange();语句注释去掉,结果如下,此时handleChange作为
HelloMessage的方法调用,this自然就指向了调用该方法的对象。因此在构造函数中需要加上this.handleChange = this.handleChange.bind(this);这一句,为handleChange绑定一个this。
在这里插入图片描述
参考:
https://www.jianshu.com/p/86267fab4878

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值