跳转到内容

JavaScript类继承

来自代码酷

JavaScript类继承[编辑 | 编辑源代码]

JavaScript类继承是面向对象编程(OOP)的核心概念之一,它允许一个类(子类)基于另一个类(父类)来创建,继承父类的属性和方法,同时可以扩展或修改它们。在JavaScript中,类继承是通过原型链(prototype chain)实现的,ES6之后引入了更简洁的`class`和`extends`语法来支持继承。

介绍[编辑 | 编辑源代码]

在JavaScript中,继承允许子类复用父类的代码,从而减少重复并提高代码的可维护性。继承的主要方式包括:

  • 原型继承(Prototypal Inheritance):基于原型链的继承。
  • 类继承(Class Inheritance):使用ES6的`class`和`extends`关键字实现。

原型继承[编辑 | 编辑源代码]

在ES6之前,JavaScript使用原型链实现继承。每个对象都有一个内部属性`Prototype`(可通过`__proto__`或`Object.getPrototypeOf()`访问),指向其父类的原型对象。

基本示例[编辑 | 编辑源代码]

// 父类
function Animal(name) {
    this.name = name;
}

Animal.prototype.speak = function() {
    console.log(`${this.name} makes a noise.`);
};

// 子类
function Dog(name) {
    Animal.call(this, name); // 调用父类构造函数
}

// 设置原型链
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// 子类方法
Dog.prototype.speak = function() {
    console.log(`${this.name} barks.`);
};

const dog = new Dog('Rex');
dog.speak(); // 输出: "Rex barks."

解释: 1. `Animal`是父类,`Dog`是子类。 2. `Dog.prototype = Object.create(Animal.prototype)`确保`Dog`继承`Animal`的原型方法。 3. `Dog.prototype.constructor = Dog`修复构造函数指向。 4. 子类可以覆盖父类方法(如`speak`)。

ES6类继承[编辑 | 编辑源代码]

ES6引入了`class`和`extends`语法,使继承更直观。

基本语法[编辑 | 编辑源代码]

class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(`${this.name} makes a noise.`);
    }
}

class Dog extends Animal {
    speak() {
        console.log(`${this.name} barks.`);
    }
}

const dog = new Dog('Rex');
dog.speak(); // 输出: "Rex barks."

解释: 1. `extends`关键字表示`Dog`继承`Animal`。 2. `super()`可在子类构造函数中调用父类构造函数(未显式调用时自动调用)。 3. 方法可被覆盖(如`speak`)。

`super`关键字[编辑 | 编辑源代码]

`super`用于调用父类的方法或构造函数:

class Cat extends Animal {
    speak() {
        super.speak(); // 调用父类的speak方法
        console.log(`${this.name} meows.`);
    }
}

const cat = new Cat('Whiskers');
cat.speak();
// 输出:
// "Whiskers makes a noise."
// "Whiskers meows."

继承链与原型链[编辑 | 编辑源代码]

JavaScript的继承基于原型链。以下是`Dog`实例的原型链示意图:

graph LR dogInstance[Dog Instance] --> Dog.prototype Dog.prototype --> Animal.prototype Animal.prototype --> Object.prototype Object.prototype --> null

实际应用案例[编辑 | 编辑源代码]

场景:UI组件继承[编辑 | 编辑源代码]

假设有一个基础`Button`类,`PrimaryButton`和`SecondaryButton`继承它:

class Button {
    constructor(text) {
        this.text = text;
    }

    render() {
        return `<button>${this.text}</button>`;
    }
}

class PrimaryButton extends Button {
    render() {
        return `<button class="primary">${this.text}</button>`;
    }
}

class SecondaryButton extends Button {
    render() {
        return `<button class="secondary">${this.text}</button>`;
    }
}

const primary = new PrimaryButton('Submit');
console.log(primary.render()); // 输出: "<button class="primary">Submit</button>"

注意事项[编辑 | 编辑源代码]

1. 多重继承:JavaScript不支持多重继承(一个子类继承多个父类),但可通过混入(Mixins)或组合实现类似功能。 2. 性能:过深的原型链可能影响性能。 3. `instanceof`检查:`instanceof`运算符基于原型链检查对象是否属于某个类。

总结[编辑 | 编辑源代码]

JavaScript类继承通过原型链或ES6的`class`/`extends`实现,允许代码复用和层次化设计。理解原型链是关键,而`super`和`extends`提供了更清晰的语法。实际开发中,继承常用于构建可扩展的组件或模块。