react中的super
1、为什么一定要在constructor中调用super
答案:如果一个子类,通过extends关键字继承父类,那么,在子类的constructor构造函数中,必须优先调用一下super()
2、super是什么东西
答案:super是一个函数,而且,它是父类的构造器,子类中的super,其实就是父类中construct构造器的一个引用
3、为什么调用super()之后,p中的name和age变成了undefined
class Hello extends React.Component{
constructor(name,age){
super()
this.name = name
this.age = age
}
}
const p = new Hello('terry',23)
console.log(p)
===========================
super关键字即可做函数使用,也可做对象使用,两种情况,用法完全不同
constructor 是一种用于创建和初始化class创建的对象的特殊方法。
(1)super做函数使用
class A {
constructor() {
console.log(new.target.name); // new.target 指向当前正在执行的函数
}
}
class B extends A{
constructor(){ //构造函数
super() //es6要求,子类的构造函数必须执行一次super()函数,否则会报错
}
}
new A() //A
new B() //B
注意:在constructor中必须调用super方法,因为子类没有自己的this对象,而是继承父类的this对象
super代表父类的构造函数,但返回子类的实例,即super内部的this指向B
所以,super()在这里相当于A.prototype.constructor.call(this, props)
(2)当对象使用
1)在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
class A {
c() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.c()); // 2
}
}
let b = new B();
子类 B 当中的 super.c(),就是将 super 当作一个对象使用。
这时,super 在普通方法之中,指向 A.prototype,所以 super.c() 就相当于 A.prototype.c()。
2)通过 super 调用父类的方法时,super 会绑定子类的 this。
class A {
constructor() {
this.x = 1;
}
s() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
m() {
super.s();
}
}
let b = new B();
b.m(); // 2
上面代码中,super.s() 虽然调用的是 A.prototytpe.s(),但是 A.prototytpe.s()会绑定子类 B 的 this,导致输出的是 2,而不是 1。也就是说,实际上执行的是 super.s.call(this)。
3)由于绑定子类的 this,所以如果通过 super 对某个属性赋值,这时 super 就是 this,赋值的属性会变成子类实例的属性。
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(super.x); // undefined
console.log(this.x); // 3
}
}
let b = new B();
上面代码中,super.x 赋值为 3,这时等同于对 this.x 赋值为 3。而当读取 super.x 的时候,调用的是 A.prototype.x,但并没有 x 方法,所以返回 undefined。
4)注意,使用 super 的时候,必须显式指定是作为函数,还是作为对象使用,否则会报错。
class A {}
class B extends A {
constructor() {
super();
console.log(super); // 报错
}
}
静态方法:在构造函数本身上定义的方法,只能通过构造函数本身调用,new出来的对象不能够调用。
实例代码:
//创建构造函数f1
function f1(){}
//静态方法
f1.static = function(){
console.log("我是一个静态方法");
}
f1.static(); // 我是一个静态方法
es6中super
class类有两个关键字:static和super
super不仅是关键字,还可作为函数对象
函数:在子类继承父类中,super作为函数调用,只能写在子类的构造函数里,super代表父类的构造函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
//Animal类
class Animal{
//1.构造函数
constructor(name,age){
this.name=name;
this.age=age;
}
//2.普通方法
sayName(){
console.log("my name is",this.name);
}
sayAge(){
console.log('my age is',this.age);
}
}
//原型链继承
class Dog extends Animal{
constructor(name,age,gender){
//等价于借用构造函数
super(name,age)
this.gender=gender;
}
sayGender(){
console.log("my gender is",this.gender);
}
}
let d = new Dog("一休",2,"male");
console.log(d);
d.sayName();
d.sayAge();
d.sayGender();
</script>
</body>
</html>
执行过时super()代表的是子类,super()里面的this指向子类的实例对象
对象:super作为对象使用时,分为普通方法中使用和在静态方法中使用
普通方法中:super指向父类的原型,即A.prototype,可以访问到原型中的方法和属性
ES6规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例