继承在 JavaScript 编程中是一个基本知识点,必须掌握的,下面就由本文简单讲解一下什么是继承。
在 JavaScript 中,继承是一种对象之间共享属性和方法的机制。它允许一个对象(称为子类)从另一个对象(称为父类)继承属性和方法,以便在子类中重用父类的功能。
原型链继承是通过将子类的原型指向父类的实例来实现的。这样,子类就可以继承父类的属性和方法。但是,这种方式有一个缺点,就是所有子类实例都会共享父类实例的属性和方法。
function Parent() {
this.name = 'parent';
}
Parent.prototype.sayHello = function() {
console.log('Hello, I am ' + this.name);
}
function Child() {
this.name = 'child';
}
Child.prototype = new Parent();
var child = new Child();
child.sayHello(); // Hello, I am child
构造函数继承是通过在子类构造函数中调用父类构造函数来实现的。这样,子类就可以继承父类的属性。但是,这种方式无法继承父类的原型上的方法。
function Parent() {
this.name = 'parent';
}
function Child() {
Parent.call(this);
this.name = 'child';
}
var child = new Child();
console.log(child.name); // child
组合继承是将原型链继承和构造函数继承结合起来的一种方式。这样,子类既可以继承父类的属性,也可以继承父类原型上的方法。
function Parent() {
this.name = 'parent';
}
Parent.prototype.sayHello = function() {
console.log('Hello, I am ' + this.name);
}
function Child() {
Parent.call(this);
this.name = 'child';
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
var child = new Child();
child.sayHello(); // Hello, I am child
原型式继承是通过创建一个临时构造函数来实现的。这个临时构造函数的原型指向父类的实例,然后返回这个临时构造函数的实例。这样,子类就可以继承父类的属性和方法。
function createObject(obj) {
function F() {}
F.prototype = obj;
return new F();
}
var parent = {
name: 'parent',
sayHello: function() {
console.log('Hello, I am ' + this.name);
}
};
var child = createObject(parent);
child.name = 'child';
child.sayHello(); // Hello, I am child
寄生式继承是在原型式继承的基础上,增强了子类实例。具体来说,可以在一个函数内部创建一个临时对象,然后将这个临时对象作为子类实例的原型,最后返回这个子类实例。
function createObject(obj) {
function F() {}
F.prototype = obj;
return new F();
}
function createChild(parent) {
var child = createObject(parent);
child.name = 'child';
child.sayHello = function() {
console.log('Hello, I am ' + this.name);
};
return child;
}
var parent = {
name: 'parent',
sayHello: function() {
console.log('Hello, I am ' + this.name);
}
};
var child = createChild(parent);
child.sayHello(); // Hello, I am child
寄生组合式继承是在组合继承的基础上,优化了父类实例的创建过程。具体来说,可以通过 Object.create() 方法来创建一个临时对象,然后将这个临时对象作为子类原型的原型,最后将子类原型的构造函数指向子类本身。
function inheritPrototype(child, parent) {
var prototype = Object.create(parent.prototype);
prototype.constructor = child;
child.prototype = prototype;
}
function Parent() {
this.name = 'parent';
}
Parent.prototype.sayHello = function() {
console.log('Hello, I am ' + this.name);
}
function Child() {
Parent.call(this);
this.name = 'child';
}
inheritPrototype(Child, Parent);
var child = new Child();
child.sayHello(); // Hello, I am child
使用 class 和 extends 关键字来实现类的继承,另外,extends 是通过 寄生组合式继承 来实现的。
class Animal {
constructor(name) {
this.name = name;
}
sayHello() {
console.log('Hello, my name is ' + this.name);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
eat() {
console.log('I am eating ...');
}
}
const myDog = new Dog('二狗', '哈士奇');
myDog.sayHello(); // 输出: Hello, my name is 二狗
myDog.eat(); // 输出: I am eating ...