ES6中构造函数内super关键字的使用
1.在ES6实现继承中会有constructor构造函数,而实现继承的子类构造函数中必须先调用super()方法,此处的super()为父类的构造方法,而如果不调用,浏览器则会报错。
class Person {
constructor(name,age){
this.name=name;
this.age=age;
}
}
class Son extends Person{
constructor(name,age){
}
}
let son=new Son(); //报错
报错原因是因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工,而 super 就代表了父类的构造函数。super 虽然代表了父类 Person 的构造函数,但是返回的是子类 Son 的实例,即 super 内部的 this 指的是 Son。正确写法:
class Person {
constructor(name,age){
this.name=name;
this.age=age;
}
}
class Son extends Person{
constructor(name,age){
super(name,age);
}
}
let son=new Son('张三',18);
此处的super(name,age)===super.call(this,name,age); 所以此时调用的父类的构造函数内的this指向的是Son实例。
需要注意的是super()方法不仅必须要调用,并且必须是子构造函数内第一行调用(最先);
2.在子类中super关键字的含义及作用
class Person {
constructor(name,age){
this.name=name;
this.age=age;
this.pname='我是父类';
}
say(){
console.log(this.name,this.age);
}
test(){
console.log('我是父类的test方法');
}
}
Person.prototype.pname='我是父类的原型上的pname';
class Son extends Person{
constructor(name,age){
super(name,age);
this.pname='我是子类';
}
test(){
console.log('我是子类的test方法')
console.log(super.pname);
//打印出 : 我是父类的原型上的pname
可得出结论 在子类中使用super.xxx变量时此时 都是访问 父类原型上的属性。
console.log(super.test());
// 打印出 :我是父类的test方法
可得出结论 在子类中super.xxx(); 调用方法都是调用父类中的方法,
其实 console.log(Person.prototype.test) 试着打印出原型上的test方法你会发现就是父类中定义的test方法。
所以综合上述结论可得出 使用super.xxx, super.xxx(); 访问属性和调用方法时都是在父类的原型上去查找
。而且如果父类没有不会找子类的,而是直接打印出undefined.
super.pname="修改pname的值";
console.log(this.pname);//访问子类本身的pname; 结果: 修改pname的值
console.log(super.pname);//访问父类原型上的pname; 结果:我是父类的原型上的pname
console.log(new Person().pname);// 访问 父类上的pname; 结果: 我是父类
结论:发现改变的是子类上的pname 值
所以可以得出结论:
当使用 super.xxx=xxx;进行为属性赋值时,此时super===this,访问的是子类
}
}
let son=new Son('张三',18);
综上所述:
console.log(super.xxx) 等于 console.log(父类.prototype.xxx);
console.log(super.xxx()) 等于 console.log(父类.prototype.xxx());
super.xxx=xxx 等于 this.xxx=xxx;