react中的class详解
ES6中的class
1. class中的this
class Point {
constructor(x, y) {
this.x = x // 1. this指向实例
this.y = y
}
toString() {
// 2. 类中的方法都定义在原型上,constructor也是一个方法
return '(' + this.x + ', ' + this.y + ')'
}
}
var point = new Point(2, 3)
point.toString() // (2, 3)
// 3. 因为this指向实例,x,y直接是定义在this对象上,所以x,y都是实例对象
// 自身的属性,而toString则是原型对象的属性,因为定义在Point类上
2. class中的set,get
class MyClass {
constructor() {
// ...
}
get prop() {
return 'getter';
}
set prop(value) {
console.log('setter: '+value);
}
}
let inst = new MyClass();
inst.prop = 123;
// setter: 123
inst.prop
// 'getter'
注意:
- class中默认严格模式
class中的this指向
类的方法内部如果含有this,它默认指向类的实例
class Logger {
printName(name = 'there') {
this.print(`Hello ${name}`);
}
print(text) {
console.log(text);
}
}
const logger = new Logger();
const { printName } = logger;
printName(); // TypeError: Cannot read property 'print' of undefined
this是指向实例的,但是从logger中解构出printName方法后,单独执行,此时this指向调用该方法时所运行的环境,由于class内部是严格模式,所以this实际指向的是undefined
解决方案一:
class Logger {
constructor() {
this.printName = this.printName.bind(this);
}
// ...
}
// 在constructor里进行this绑定后,实例本身就有printName方法了,不再是从原型链上寻找,且this指向实例本身
解决方案二:
class Obj {
constructor() {
this.getThis = () => this;
}
}
const myObj = new Obj();
myObj.getThis() === myObj // true
箭头函数内部的this总是指向定义时所在的对象。上面代码中,箭头函数位于构造函数内部,它的定义生效的时候,是在构造函数执行的时候。这时,箭头函数所在的运行环境,肯定是实例对象,所以this会总是指向实例对象。
测试
代码1:
// 使用 ES6 的 class 语法
class Cat {
sayThis () {
console.log(this); // 这里的 `this` 指向谁?
}
exec (cb) {
cb();
}
render () {
this.exec(this.sayThis);
}
}
const tom = new Cat();
tom.render(); // 输出结果是什么?
代码2:
const jerry = {
sayThis: function () {
console.log(this); // 这里的 `this` 指向谁?
},
exec: function (cb) {
cb();
},
render: function () {
this.exec(this.sayThis);
},
}
jerry.render();
React中的class
react类组件中的this丢失啦!
场景1:
import React, { Component } from 'react'
export default class App3 extends Component {
constructor(props){
super(props)
this.state = {
num:1
}
}
render() {
return (
<>
<p>数字为:{this.state.num}</p>
{/* <button onClick={()=>{this.setState({num:this.state.num+1})}}>累加1</button> */}
<button onClick={this.addNum}>累加2</button>
</>
)
}
addNum(){
this.setState({num:this.state.num+1})
}
}
原因:由于点击时调用的是onClick,而onClick是Dom中的行为,this指向onClick调用的环境,所以丢失了
解决方法
import React, { Component } from 'react'
export default class App3 extends Component {
constructor(props){
super(props)
this.state = {
num:1
}
// this.addNum = this.addNum.bind(this) //累加3
}
render() {
return (
<>
<p>数字为:{this.state.num}</p>
{/* <button onClick={()=>{this.setState({num:this.state.num+1})}}>累加1</button> */}
{/* <button onClick={this.addNum.bind(this)}>累加2</button> */}
{/* <button onClick={this.addNum}>累加3</button> */}
<button onClick={()=>{this.addNum()}}>累加4</button>
</>
)
}
addNum(){
this.setState({num:this.state.num+1})
}
}