阅读 289

让你彻底搞懂React类组件

一.原生js中的类

//创建一个Person类
class Person {
    constructor(name,age) {
        this.name = name; //构造器中的this就是类的实例化对象
        this.age = age;
    }
    //给类添加方法,此方法放在了类的实例对象上,供类的实例对象调用。
    speak() {
        console.log(`我的名字是&{this.name},我的年龄是&{this.age}`)
    }
}
//创建一个Student类,继承Person
class Student extends Person {
    constructor(name,age,grad){
        super(name,age)
        this.grad = grad
    }
}
const S1 = new Student('小明', 18, '高三')
复制代码

二、js类

2.1类解释

当我们在控制台打印实例对象时,会看到类似于这样的代码,Person{},这代表是Person的实例对象,因为打印一个{},并不能辨别是什么。当给类添加属性和方法时,利用constructor构造器接收参数并且给对象添加属性,如上图所示。注意:构造器中的this就是所创建出来的实例对象。当给对象添加方法时,在constructor后面写方法,调用时,利用实例对象.方法(),方法中的this指向实例对象。

2.2类的继承

如上图所示,class 子类 extends 父类,因为有继承,所以子类会继承父类constructor中的属性和方法,并且当在子类没有添加方法时,仍然可以使用父类的方法,因为按照对象属性和方法的访问形式,也就是原型链,当在自身找不到时,会向上查找。在Object的原型链上没有时,会返回undefined。

2.3关于子类中写不写constructor的问题

当在子类中添加新的属性时,需要用到constructor,在里面写自定义的属性,当子类继承父类,并且子类写了constructor,在子类中必须写super()关键字,super用来继承父类中的属性。 当子类写了父类中的同名方法后,按照原型链,先用本身有的。

三、react类组件中的常用问题

3.1类组件中的render()方法是怎么调用的?

当将类组件当作组件使用时,react发现为一个类组件,所以react内部new出来一个实例,调用render()方法,render方法在子组件的以原型对象上。

3.2为什么要改变方法的this指向,或者为什么写方法时,我们要写成箭头函数?

在类组件中,我们常可以看到在constructor中类似于这样的代码: this.change = this.change.bind(this),我们为什么要改变this指向呢?因为change方法定义在子类的原型对象上。在类中,默认开启了局部严格模式,所以change方法中的this是undefined。我们解析这句赋值语句代码,右边部分this.change中的this是子类的实例对象,实例对象.change即可找到原型对象上的change方法。采用bind改变this指向时,返回一个已经被改变this指向的新函数。外部定义change方法接收,并且挂载在子类的实例对象上。所以当我们调用change方法时,按照原型链,应该找到的是实例本身的chang方法,而不是实例原型对象上的change。

3.3在实际开发中优化类组件的写法

首先constructor写是为了初始化状态和接props,在代码运行中constructor只被调用一次,而render被调用1+n次,即状态更新就会调用render方法。在类中我们在constructor外写类似于这样的代码 a=1 ,即可在子类的实例对象上添加 a=1 这样一个属性。所以可以不用写constructor,直接写 state={} 的形式。对于函数的优化,可以用箭头函数与a=1的形式 即 变量名 = () => {}的形式,不用再用bind改变this指向。因为箭头函数中的this指向的函数的上下文。

3.4类中的static关键字的作用(静态方法和静态属性是不能被继承的)

为了使得代码结构更加清晰,在类组件中使用到props的验证时,会看到这样的代码:子类.propTypes = {},所以可以采用static关键字使得将propTypes方法添加在子类上,而不是实例对象上,使得代码结构更清晰。

文章分类
前端
文章标签