1. 继承
- 现实中的继承:子承父业,比如我们都继承了父亲的姓。
- 程序中的继承:子类可以继承父类的—些属性和方法。
使用 extends 关键字实现继承
js
class Son extends Father {
// class body
}class Son extends Father {
// class body
}2. super 关键字
super 关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数。
js
super([arguments]);
// 调用 父对象/父类 的构造函数
super.functionOnParent([arguments]);
// 调用 父对象/父类 上的方法
Copy to clipboardErrorCopiedsuper([arguments]);
// 调用 父对象/父类 的构造函数
super.functionOnParent([arguments]);
// 调用 父对象/父类 上的方法
Copy to clipboardErrorCopied示例:
js
class Person {
constructor (uname, age) {
this.uname =uname;
this.age = age;
}
}
class Student extends Person {
constructor (uname, age, major) {
// super 将子类的参数传递给父类构造函数,减少代码量
super(uname, age);
// 子类可以有自己独有的属性
this.major = major;
}
}
let rick = new Student("Rick", 22, "数学");class Person {
constructor (uname, age) {
this.uname =uname;
this.age = age;
}
}
class Student extends Person {
constructor (uname, age, major) {
// super 将子类的参数传递给父类构造函数,减少代码量
super(uname, age);
// 子类可以有自己独有的属性
this.major = major;
}
}
let rick = new Student("Rick", 22, "数学");WARNING
注意: 子类在构造函数中使用 super, 必须放到 this 前面(必须先调用父类的构造方法,再使用子类构造方法)
3. super 传值问题
观察以下代码,运行将产生错误。
js
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor(x, y) {
this.x = this.x;
this.y = this.y;
}
}
let obj = new Son(10, 20);
obj.sum();class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor(x, y) {
this.x = this.x;
this.y = this.y;
}
}
let obj = new Son(10, 20);
obj.sum();解释说明:若子类没有写构造函数 constructor,则实例化时默认调用父类的,这时候程序运行无误。若子类写了构造函数,那么子类在调用 sum 方法的时候,参数的值没有传给父类,父类无法调用参数的值,也就无法执行 sum 方法。
正确:加入 super。
js
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor(x, y) {
super(x, y);
}
}
let obj = new Son(10, 20);
obj.sum(); // 30class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor(x, y) {
super(x, y);
}
}
let obj = new Son(10, 20);
obj.sum(); // 304. super 调用父类普通函数
js
class Parent {
sayHi() {
return "Father: hello";
}
}
class Child extends Parent {
sayHi() {
// super 调用父类普通函数
console.log(super.sayHi());
}
}
let man = new Child();
man.sayHi(); // Father: helloclass Parent {
sayHi() {
return "Father: hello";
}
}
class Child extends Parent {
sayHi() {
// super 调用父类普通函数
console.log(super.sayHi());
}
}
let man = new Child();
man.sayHi(); // Father: hello5. 继承中属性和方法查找原则
继承中的属性或者方法查找原则:就近原则
- 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
- 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)
js
class Parent {
sayHi() {
console.log("Father: hello");
}
}
class Child extends Parent {
sayHi() {
console.log("Son: hello");
}
}
let man = new Child();
man.sayHi(); // Son: helloclass Parent {
sayHi() {
console.log("Father: hello");
}
}
class Child extends Parent {
sayHi() {
console.log("Son: hello");
}
}
let man = new Child();
man.sayHi(); // Son: hello6. super 必须放到子类 this 之前
子类在构造函数中使用 super, 必须放到 this 前面。
js
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class Son extends Father {
constructor(x, y, z) {
super(x, y, z);
this.z = this.z;
}
}
let obj = new Son();class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class Son extends Father {
constructor(x, y, z) {
super(x, y, z);
this.z = this.z;
}
}
let obj = new Son();使用类的注意点
- 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象
- 类里面的共有属性和方法一定要加 this 使用
- 类里面的 this 指向问题:constructor 里面的 this 指向实例对象, 方法里面的 this 指向这个方法的调用者
liang14658fox