JavaScript高级程序设计继承(一)

简介: ES6 类支持单继承。使用 extends 关键字,就可以继承任何拥有[[Construct]]和原型的对象。 很大程度上,这意味着不仅可以继承一个类,也可以继承普通的构造函数(保持向后兼容):

👦个人简介:张清悠,字澄澈,号寻梦客,爱好旅行、运动,主攻前端方向技术研发,副攻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. 构造函数、HomeObjectsuper()

派生类的方法可以通过 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高级程序设计(一)继承
会持续更新中…
原创不易,期待您的点赞关注与转发评论😜😜

目录
相关文章
|
2月前
|
JavaScript 前端开发 Java
使用JavaScript进行面向对象编程的指南
使用JavaScript进行面向对象编程的指南
25 4
|
3月前
|
设计模式 前端开发 JavaScript
深入认识:JavaScript中的面向对象
深入认识:JavaScript中的面向对象
35 0
|
JavaScript 前端开发 Java
【JavaScript面向对象详解】
【JavaScript面向对象详解】
131 0
|
人工智能 JavaScript 前端开发
JavaScript高级程序设计继承(二)
有时候可能需要定义这样一个类,它可供其他类继承,但本身不会被实例化。虽然 ECMAScript 没 有专门支持这种类的语法 ,但通过 new.target 也很容易实现。new.target 保存通过 new 关键字调 用的类或函数。通过在实例化时检测 new.target 是不是抽象基类,可以阻止对抽象基类的实例化:
137 0
|
JavaScript 前端开发
JavaScript 面向对象之继承
JavaScript 面向对象之继承
115 0
JavaScript 面向对象之继承
|
JavaScript 前端开发 关系型数据库
【JavaScript】26_面向对象——继承
# 8、继承 - 可以通过extends关键来完成继承 时,就相当于将另一个类中的代码复制到了当前类中(简单理解) - 继承发生时,被继承的类称为 父类(超类),继承的类称为 子类 的代码,并且可以在不修改一个类的前提对其进行扩展 ​ 封装 —— 安全性 ​ 继承 —— 扩展性 ​ 多态 —— 灵活性 ```html <script> class Animal{ constructor(name){ this.n
66 0
|
JavaScript 前端开发
JavaScript面向对象详解(三)
继承是面向对象中非常重要的特性. ES5中和类的实现一样, 不能直接实现继承. 实现继承主要是依靠原型链来实现的。
96 0
JavaScript面向对象详解(三)
|
JavaScript 前端开发
JavaScript面向对象详解(二)
前面, 我们讨论了很多种场景对象的方式: 从Object到字面量, 再到工厂模式, 再到构造函数. 最终我们发现, 构造函数是比较理想的一种方式, 但是它也存在问题. 为了最终解决这个问题, 我们需要学习一个新的知识: 原型(prototype).
52 0
JavaScript面向对象详解(二)
|
存储 前端开发 JavaScript
JavaScript进阶之继承
JavaScript进阶之继承
65 0
JavaScript进阶之继承
|
JSON JavaScript 前端开发
JavaScript面向对象详解(四)
在上一篇中, 我们讨论了ES5中, 实现继承的一些方式. 在最后, 我们说了组合继承是相对完美的解决方案, 但是它也存在一些问题. 这篇文章, 我们就通过某种新的模式, 给出一种目前使用最多, 也是我们最终的解决方案.
101 0