js的2种继承方式详解


在JavaScript中,继承是面向对象编程的一个重要概念,它允许我们基于一个已存在的类(父类)来创建一个新类(子类),这个新类可以继承父类的属性和方法。JavaScript中主要有两种继承方式:原型链继承(Prototype Chain Inheritance)和类继承(Class Inheritance,通过ES6中的`class`关键字和`extends`关键字实现)。

### 1. 原型链继承

在JavaScript中,每个函数都有一个`prototype`属性,这个属性是一个对象,它默认包含一个`constructor`属性,指向函数本身。同时,每个实例对象都有一个内部属性`[[Prototype]]`(在ES5中通过`__proto__`属性访问,但这是一个非标准属性,应使用`Object.getPrototypeOf()`来获取),这个内部属性指向创建它的构造函数的`prototype`属性。原型链继承正是基于这种机制实现的。


function Parent(name) {
    this.name = name;
}

Parent.prototype.sayHello = function() {
    console.log('Hello, ' + this.name);
};

function Child(name, age) {
    Parent.call(this, name); // 借用构造函数继承属性
    this.age = age;
}

// 原型链继承方法
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

Child.prototype.sayAge = function() {
    console.log(this.age);
};

var child = new Child('Alice', 30);
child.sayHello(); // Hello, Alice
child.sayAge(); // 30

### 2. 类继承(ES6)

ES6引入了`class`关键字和`extends`关键字,使得JavaScript的继承更加直观和易于理解。类继承是基于原型链继承的语法糖。


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

    sayHello() {
        console.log('Hello, ' + this.name);
    }
}

class Child extends Parent {
    constructor(name, age) {
        super(name); // 调用父类的constructor
        this.age = age;
    }

    sayAge() {
        console.log(this.age);
    }
}

const child = new Child('Bob', 25);
child.sayHello(); // Hello, Bob
child.sayAge(); // 25

在类继承中,`super`关键字用于调用父类的构造函数和方法。通过`extends`关键字,子类可以继承父类的所有属性和方法,并且可以通过定义相同名称的属性和方法来覆盖它们。

以上就是对JavaScript中两种主要继承方式的详细解释。