简述ES6 Class、extends是什么,有什么作用?

参考回答

在 ES6 中,classextends 提供了更加直观和结构化的方式来创建和继承对象。

  1. class 是 ES6 提供的语法糖,用来定义类。它封装了对象的属性和方法,使代码更清晰、更易维护,支持构造函数和原型方法的定义。
  2. 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. 应用场景

  • 封装和复用:通过 classextends,可以轻松地封装逻辑并复用代码。
    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. classextends 的底层机制

  • 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. 注意事项

  1. 必须使用 new 调用类class 不能像普通函数那样直接调用,否则会抛出错误。
    class Example {}
    Example(); // TypeError: Class constructor Example cannot be invoked without 'new'
    
  2. super 的使用限制
    • 在子类构造函数中,必须在使用 this 之前调用 super()
    • super() 用于调用父类的构造函数。
    class Parent {
     constructor(name) {
       this.name = name;
     }
    }
    class Child extends Parent {
     constructor(name, age) {
       super(name); // 必须调用
       this.age = age;
     }
    }
    
  3. 类的静态方法和实例方法的区别
    静态方法直接挂载在类上,而实例方法挂载在类的原型上。


总结

  • class 提供了面向对象编程的语法糖,方便定义和组织对象的属性与方法。
  • extends 实现了类的继承,支持代码复用和扩展,是构建复杂层次结构的重要工具。
  • classextends 的使用提升了代码的可读性和组织性,同时让 JavaScript 更接近传统的面向对象编程语言。

发表评论

后才能评论