👦个人简介:张清悠,字澄澈,号寻梦客,爱好旅行、运动,主攻前端方向技术研发,副攻Unity 3D、C++、Python人工智能等
📝个人寄语:学会不为过程的缓慢而焦虑,即使暂时未能如你所愿,但只要你在努力,你就在不断成长!
🙏个人公众号:清悠小猿(海量源码尽在其中,欢迎关注)
前言:
ES6 类支持单继承。使用 extends 关键字,就可以继承任何拥有[[Construct]]和原型的对象。
很大程度上,这意味着不仅可以继承一个类,也可以继承普通的构造函数(保持向后兼容):
1.继承基础
继承类
class Vehicle {
}
class Bus extends Vehicle {
}
let b = new Bus();
console.log(b instanceof Bus); // true
console.log(b instanceof Vehicle); // true
function Person() {
}
继承普通构造函数
class Engineer extends Person {
}
let e = new Engineer();
console.log(e instanceof Engineer); // true
console.log(e instanceof Person); // true
派生类都会通过原型链访问到类和原型上定义的方法。this 的值会反映调用相应方法的实例或者类:
class Vehicle {
identifyPrototype(id) {
console.log(id, this);
}
static identifyClass(id) {
console.log(id, this);
}
}
class Bus extends Vehicle {
}
let v = new Vehicle();
let b = new Bus();
b.identifyPrototype('bus'); // bus, Bus {}
v.identifyPrototype('vehicle'); // vehicle, Vehicle {}
Bus.identifyClass('bus'); // bus, class Bus {}
Vehicle.identifyClass('vehicle'); // vehicle, class Vehicle {}
注意: extends 关键字也可以在类表达式中使用,因此 let Bar = class extends Foo {}
是有效的语法。
2. 构造函数、HomeObject 和 super()
派生类的方法可以通过 super 关键字引用它们的原型。这个关键字只能在派生类中使用,而且仅
限于类构造函数、实例方法和静态方法内部。在类构造函数中使用 super 可以调用父类构造函数。
class Vehicle {
constructor() {
this.hasEngine = true;
}
}
class Bus extends Vehicle {
constructor() {
不要在调用 super()之前引用 this,否则会抛出 ReferenceError
super(); // 相当于 super.constructor()
console.log(this instanceof Vehicle); // true
console.log(this); // Bus { hasEngine: true }
}
}
new Bus();
在静态方法中可以通过 super 调用继承的类上定义的静态方法:
class Vehicle {
static identify() {
console.log('vehicle');
}
}
class Bus extends Vehicle {
static identify() {
super.identify();
}
}
Bus.identify(); // vehicle
注意: ES6 给类构造函数和静态方法添加了内部特性[[HomeObject]],这个特性是一个
指针,指向定义该方法的对象。这个指针是自动赋值的,而且只能在 JavaScript 引擎内部
访问。super 始终会定义为[[HomeObject]]的原型。
在使用 super 时要注意几个问题。
super 只能在派生类构造函数和静态方法中使用。
class Vehicle {
constructor() {
super();
// SyntaxError: 'super' keyword unexpected
}
}
不能单独引用 super 关键字,要么用它调用构造函数,要么用它引用静态方法。
class Vehicle {
}
class Bus extends Vehicle {
constructor() {
console.log(super);
// SyntaxError: 'super' keyword unexpected here
}
}
调用 super()会调用父类构造函数,并将返回的实例赋值给 this。
class Vehicle {
}
class Bus extends Vehicle {
constructor() {
super();
console.log(this instanceof Vehicle);
}
}
new Bus(); // true
super()的行为如同调用构造函数,如果需要给父类构造函数传参,则需要手动传入。
class Vehicle {
constructor(licensePlate) {
this.licensePlate = licensePlate;
}
}
class Bus extends Vehicle {
constructor(licensePlate) {
super(licensePlate);
}
}
console.log(new Bus('1337H4X')); // Bus { licensePlate: '1337H4X' }
如果没有定义类构造函数,在实例化派生类时会调用 super(),而且会传入所有传给派生类的
class Vehicle {
constructor(licensePlate) {
this.licensePlate = licensePlate;
}
}
class Bus extends Vehicle {
}
console.log(new Bus('1337H4X')); // Bus { licensePlate: '1337H4X' }
在类构造函数中,不能在调用 super()之前引用 this。
class Vehicle {
}
class Bus extends Vehicle {
constructor() {
console.log(this);
}
}
new Bus();
// ReferenceError: Must call super constructor in derived class
// before accessing 'this' or returning from derived constructor
如果在派生类中显式定义了构造函数,则要么必须在其中调用 super(),要么必须在其中返回
一个对象。
class Vehicle {
}
class Car extends Vehicle {
}
class Bus extends Vehicle {
constructor() {
super();
}
}
class Van extends Vehicle {
constructor() {
return {
};
}
}
console.log(new Car()); // Car {}
console.log(new Bus()); // Bus {}
console.log(new Van()); // {}
总结
```
以上就是今天的JavaScript高级程序设计(一)继承
会持续更新中…
原创不易,期待您的点赞关注与转发评论😜😜