推荐答案
ES6 引入的 class 关键字提供了一种更接近传统面向对象编程的语法糖,用于定义类。它本质上仍然是基于原型(prototype)的,但提供了更清晰的语法结构。
类 (Class):
class关键字用于定义类,可以包含构造函数constructor、实例方法、静态方法等。constructor方法是类的构造函数,用于创建和初始化类的实例。- 实例方法定义在类的原型
prototype上,可以通过类的实例进行调用。 - 静态方法定义在类本身上,可以通过类名直接调用。
继承 (Inheritance):
extends关键字用于实现类之间的继承,子类继承父类的属性和方法。- 子类可以使用
super()调用父类的构造函数,以便初始化父类的属性。 - 子类可以重写(override)父类的方法,实现多态。
- 子类还可以添加新的属性和方法,扩展父类的功能。
实现类的继承:
使用 extends 关键字,并在子类的构造函数中使用 super() 调用父类的构造函数,这是实现继承的基本方法。
// www.javascriptcn.com code example
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log("Generic animal sound");
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 调用父类构造函数
this.breed = breed;
}
speak() {
console.log("Woof!"); // 重写父类方法
}
fetch() {
console.log("Fetching!");
}
}
let myDog = new Dog("Buddy", "Golden Retriever");
myDog.speak(); // 输出 "Woof!"
myDog.fetch(); // 输出 "Fetching!"
console.log(myDog.name); // 输出 "Buddy"本题详细解读
ES6 Class 的本质
ES6 的 class 关键字并非创建了一种新的对象模型,它仅仅是 JavaScript 原型继承的语法糖。这意味着在底层,class 仍然使用原型链来实现继承和实例化。
- 构造函数 (
constructor):constructor方法在class中扮演着构造函数的角色。当我们使用new关键字创建一个类的实例时,constructor方法会被自动调用。 - 原型链 (
prototype): 类中定义的方法会自动添加到类的prototype属性上。这意味着所有类的实例共享相同的方法,从而节省内存。 - 静态方法 (
static): 使用static关键字定义的方法属于类本身,而不是类的实例。它们不能通过实例进行调用,通常用于创建工具函数或与类相关的操作。
extends 关键字实现继承
extends 关键字是实现 ES6 类继承的核心。它允许一个类继承另一个类的属性和方法。
- 原型继承:
extends的底层实现依然是原型继承。它建立了子类的prototype指向父类prototype的原型链关系,使得子类的实例可以访问父类的方法和属性。 super()的作用: 在子类的constructor方法中,super()必须在访问this之前被调用。它会调用父类的constructor,使得子类实例可以继承父类的属性。如果不调用super(),子类将无法访问this关键字。- 方法重写 (Override): 子类可以定义与父类同名的方法,从而重写父类的方法,实现多态。当子类实例调用该方法时,会执行子类的方法而不是父类的方法。
继承的应用场景
- 代码复用: 继承能够有效地复用代码,避免重复编写相同的逻辑。
- 创建层级结构: 使用继承可以创建具有层次结构的对象,如 UI 组件、游戏角色等。
- 实现多态: 子类可以重写父类的方法,实现不同的行为,增加程序的灵活性和可扩展性。
注意事项
this的绑定: 在class中,this关键字的绑定规则与传统的 JavaScript 函数相同,需要特别注意。箭头函数可以简化绑定问题。super()调用: 必须在子类构造函数中正确调用super(),否则会出现错误。- 静态属性和静态方法的继承: 静态属性和方法也会被继承。