红宝书第十一讲:超易懂版「ES6类与继承」零基础教程:用现实例子+图解实现
红宝书第十一讲:超易懂版「ES6类与继承」零基础教程:用现实例子+图解实现
资料取自《JavaScript高级程序设计(第5版)》。
查看总目录:红宝书学习大纲
一、ES6类的核心语法:把事物抽象成“模板”
想象你要设计一款「动物养成游戏」,需要创建多种动物对象。ES6的class
就是一个代码模板:
// 基础类(Animal是模板,有名称和吃东西方法)
class Animal {
constructor(name) { // 构造函数,初始化属性
this.name = name;
}
// 实例方法(所有动物都会吃)
eat(food) {
console.log(`${this.name}吃${food}`);
}
// 静态方法(属于类本身,动物总数统计)
static count() {
console.log(`动物园共有${Animal.total}只动物`);
}
}
Animal.total = 0; // 静态属性(新语法需使用static声明)
// 创建实例
const dog = new Animal("旺财");
dog.eat("骨头"); // "旺财吃骨头" ✅
Animal.total++; // 静态属性通过类名访问
Animal.count(); // "动物园共有1只动物"
🎯 重点说明:
constructor()
:相当于设定初始值的函数(new
触发)- 实例方法:定义行为(如
eat()
,需实例调用) static
静态方法:属于类本身(如count()
,类直接调用)
二、继承:子类复用父类能力的秘诀
假设需要新增「猫类」,会继承动物的基础能力,并新增「爬树」方法:
class Cat extends Animal { // ✨关键:extends继承
constructor(name, color) {
super(name); // 🔑调用父类构造函数
this.color = color;
}
// 新增方法(只有猫会爬树)
climbTree() {
console.log(`${this.name}正在爬树`);
}
// 覆盖父类方法(修改猫的吃法)
eat(food) {
super.eat(food); // 复用父类的eat方法
console.log("优雅地舔爪子!");
}
}
// 测试继承
const cat = new Cat("小白", "白色");
cat.eat("鱼");
// "小白吃鱼"
// "优雅地舔爪子!" ✅
cat.climbTree(); // "小白正在爬树" ✅
console.log(cat instanceof Animal); // true ✅
语法要点:
extends
关键字:让子类继承父类super()
:调用父类构造函数(必须放在子类构造第一行)- 方法覆盖:子类可重写父类方法(比如
eat()
)
三、继承的原理:原型链的“自动连接”
ES6类本质是基于原型的语法糖(背后仍用原型链实现继承)1。通过extends
,子类的原型会指向父类的实例:
// 手动验证原型链
console.log(Cat.prototype.__proto__ === Animal.prototype); // true ✅
- 子类实例先找自身方法 → 找不到则沿原型链向上查找(父类→祖父类…)
四、特殊继承技巧:继承传统构造函数
ES6类还可以继承旧版JS的函数构造函数(保持兼容性)2:
// ES5风格的构造函数(旧代码)
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
console.log(`你好,我是${this.name}`);
};
// ES6类继承构造函数
class Engineer extends Person {
constructor(name, skill) {
super(name);
this.skill = skill;
}
}
const engineer = new Engineer("张三", "JavaScript");
engineer.sayHi(); // "你好,我是张三" ✅
✅ 说明:旧代码无需修改,可直接用extends
继承!
五、总结表格:ES6类语法速查
功能 | 语法示例 | 说明 |
---|---|---|
定义类 | class 类名 { ... } | 大写开头,驼峰命名 |
构造函数 | constructor() { ... } | 只能有一个构造函数 |
定义实例方法 | 方法名() { ... } | 实例调用 |
静态方法/属性 | static 方法名() { ... } | 类名调用,如Animal.count() |
继承父类 | class 子类 extends 父类 { ... } | 子类继承父类能力 |
调用父类构造函数 | super(参数) | 必须放在子类构造第一行 |
调用父类方法 | super.父类方法名() | eat() 中调用父类方法 |
目录:总目录
上篇文章:红宝书第十讲:「构造函数与原型链」入门及深入解读:用举例子+图画理解“套娃继承”
脚注
ES6类本质是对原型继承的语法封装,保留原型链特性但语法更清晰。来源:《JavaScript高级程序设计(第5版)》指出ES6类是对传统原型方式的抽象优化。 ↩︎
extends
关键字不仅支持类间的继承,还可兼容旧版函数构造函数实现继承。来源:《JavaScript高级程序设计(第5版)》中关于Engineer类继承Person构造函数的示例。 ↩︎