简述ES6 Class、extends是什么,有什么作用?
参考回答
在 ES6 中,class 和 extends 提供了更加直观和结构化的方式来创建和继承对象。
class是 ES6 提供的语法糖,用来定义类。它封装了对象的属性和方法,使代码更清晰、更易维护,支持构造函数和原型方法的定义。extends是 ES6 用于实现继承的关键字,可以让子类继承父类的属性和方法,方便代码的复用和扩展。
示例:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`{this.name} makes a sound.`);
}
}
class Dog extends Animal {
speak() {
console.log(`{this.name} barks.`);
}
}
const dog = new Dog('Buddy');
dog.speak(); // 输出: Buddy barks.
详细讲解与拓展
1. class 的特点
- 语法糖:
class本质上是对 ES5 中构造函数和原型链的语法封装。 - 构造函数:使用
constructor方法定义类的构造函数,它会在创建实例时调用。 - 方法定义:类中定义的方法是挂载在原型上的。
- 严格模式:类的代码自动采用严格模式,无需显式声明
"use strict"。 - 不可枚举性:类中定义的方法是不可枚举的(
enumerable: false)。 - 支持静态方法:使用
static关键字定义静态方法,直接通过类调用,而不是实例。
示例:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
static species() {
return 'Homo sapiens';
}
}
const john = new Person('John', 30);
john.greet(); // 输出: Hello, my name is John.
console.log(Person.species()); // 输出: Homo sapiens
2. extends 的特点
- 继承父类属性和方法:子类通过
extends关键字继承父类,继承后可以复用父类的构造函数、实例方法和静态方法。 - 调用父类的构造函数:在子类中需要通过
super()调用父类的构造函数,完成父类属性的初始化。 - 重写父类方法:子类可以根据需要重写父类的方法,同时可以通过
super.methodName()调用父类的方法。 - 支持多层继承:
extends支持多层级的类继承。
示例:
class Animal {
constructor(name) {
this.name = name;
}
move() {
console.log(`{this.name} is moving.`);
}
}
class Bird extends Animal {
move() {
super.move(); // 调用父类方法
console.log(`{this.name} is flying.`);
}
}
const bird = new Bird('Eagle');
bird.move();
// 输出:
// Eagle is moving.
// Eagle is flying.
3. 应用场景
- 封装和复用:通过
class和extends,可以轻松地封装逻辑并复用代码。class Vehicle { constructor(make, model) { this.make = make; this.model = model; } start() { console.log(`{this.make}{this.model} is starting.`); } } class Car extends Vehicle { drive() { console.log(`{this.make}{this.model} is driving.`); } } const myCar = new Car('Toyota', 'Corolla'); myCar.start(); // 输出: Toyota Corolla is starting. myCar.drive(); // 输出: Toyota Corolla is driving. - 创建层次化结构:比如,描述动物、交通工具等场景时,使用继承来表示不同层次的行为和特性。
4. class 和 extends 的底层机制
-
class的本质:
class是基于原型链实现的语法糖。等价的 ES5 写法:// ES6 class class Person { constructor(name) { this.name = name; } greet() { console.log(`Hello, my name is {this.name}.`); } } // 等价于 ES5 function Person(name) { this.name = name; } Person.prototype.greet = function() { console.log(`Hello, my name is{this.name}.`); }; extends的本质:
extends是通过Object.create来实现子类对父类的继承。等价的 ES5 写法:
function Animal(name) { this.name = name; } Animal.prototype.move = function() { console.log(`{this.name} is moving.`); }; function Bird(name) { Animal.call(this, name); // 调用父类构造函数 } Bird.prototype = Object.create(Animal.prototype); // 继承父类方法 Bird.prototype.constructor = Bird; Bird.prototype.move = function() { Animal.prototype.move.call(this); // 调用父类方法 console.log(`{this.name} is flying.`); };
5. 注意事项
- 必须使用
new调用类:class不能像普通函数那样直接调用,否则会抛出错误。class Example {} Example(); // TypeError: Class constructor Example cannot be invoked without 'new' super的使用限制:- 在子类构造函数中,必须在使用
this之前调用super()。 super()用于调用父类的构造函数。
class Parent { constructor(name) { this.name = name; } } class Child extends Parent { constructor(name, age) { super(name); // 必须调用 this.age = age; } }- 在子类构造函数中,必须在使用
-
类的静态方法和实例方法的区别:
静态方法直接挂载在类上,而实例方法挂载在类的原型上。
总结
class提供了面向对象编程的语法糖,方便定义和组织对象的属性与方法。extends实现了类的继承,支持代码复用和扩展,是构建复杂层次结构的重要工具。class和extends的使用提升了代码的可读性和组织性,同时让 JavaScript 更接近传统的面向对象编程语言。