JS Class继承

JS Class继承

JS Class继承

什么是继承

在面向对象编程中,继承是指一个对象(称作子类)通过复制另一个对象(称作父类)的属性和方法,从而拥有了父类的行为特征。继承允许子类重用父类的代码,并且可以根据需要添加或修改自己的属性和方法。

继承可以提高代码的复用性、可维护性和可扩展性。当一个类需要具有父类的部分或全部特性时,可以使用继承来实现。

原型链继承

在传统的 JavaScript 中,继承通常是通过原型链实现的。每个对象都有一个原型对象,可以作为该对象的父类或原型对象的子类的原型。通过原型链,子类可以继承父类的属性和方法。

示例代码

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

Animal.prototype.sayHi = function() {
  console.log('Hi, I am ' + this.name);
}

function Cat(name) {
  Animal.call(this, name);
}

Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;

Cat.prototype.meow = function() {
  console.log('Meow');
}

var cat = new Cat('Tom');
cat.sayHi(); // Hi, I am Tom
cat.meow(); // Meow

代码说明

  1. 创建了一个 Animal 构造函数,接受一个 name 参数,并将其赋值给实例的 name 属性。Animal.prototype.sayHi 是一个方法,用来打印出实例的名字。
  2. 创建了一个 Cat 构造函数,继承了 Animal 构造函数的属性和方法。使用 Animal.call(this, name) 调用父类的构造函数,并将 this(即子类的实例)作为上下文,传入 name 参数。
  3. 使用 Object.create(Animal.prototype)Cat.prototype 的原型对象设置为 Animal.prototype 的实例,建立父子类原型对象之间的连接。然后通过 Cat.prototype.constructor = Cat 解决 constructor 属性指向问题,使得 Cat.prototype 指向 Cat 构造函数。
  4. Cat.prototype 上添加一个 meow 方法,定义猫独有的行为。
  5. 创建了一个名为 catCat 实例,并通过调用其继承自 AnimalsayHi 方法和猫自己的 meow 方法分别输出字符串。

运行结果

Hi, I am Tom
Meow

代码分析

在原型链继承中,通过 Object.create(Animal.prototype) 将子类的原型对象指向父类的原型对象,从而实现继承。这样一来,子类的实例就能够访问到父类原型对象上的属性和方法,在子类的原型对象上添加的新方法也会被子类的实例继承。

原型链继承的优点是简单易懂,而且灵活性较高。但是也有一些缺点,其中之一是父类的构造函数会被多次调用。例如,在上面的示例中,我们调用 Animal.call(this, name) 既在 Cat.prototype 上调用了父类的构造函数又在 Cat 实例上调用了一次,导致了一次父类构造函数的重复执行。

构造函数继承

为了解决原型链继承中父类构造函数被多次调用的问题,可以使用构造函数继承。在构造函数继承中,通过在子类的构造函数中调用父类的构造函数来继承父类的属性。

示例代码

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

Animal.prototype.sayHi = function() {
  console.log('Hi, I am ' + this.name);
}

function Cat(name) {
  Animal.call(this, name);
}

var cat = new Cat('Tom');
cat.sayHi(); // Hi, I am Tom

代码说明

  1. 创建了一个 Animal 构造函数,接受一个 name 参数,并将其赋值给实例的 name 属性。Animal.prototype.sayHi 是一个方法,用来打印出实例的名字。
  2. 创建了一个 Cat 构造函数,调用 Animal.call(this, name) 来继承父类的属性,并将 this(即子类的实例)作为上下文,传入 name 参数。
  3. 创建了一个名为 catCat 实例,并通过调用其继承自 AnimalsayHi 方法输出字符串。

运行结果

Hi, I am Tom

代码分析

在构造函数继承中,通过在子类构造函数中调用父类的构造函数来继承父类的属性。这样做的好处是可以避免父类构造函数被多次调用的问题。

然而,构造函数继承也有缺点:子类无法继承父类原型对象上的方法。在上面的示例中,Cat 实例无法访问到 Animal.prototype 上的方法 sayHi

组合继承

为了克服原型链继承和构造函数继承的缺点,我们可以使用组合继承。组合继承是同时使用原型链继承和构造函数继承的一种模式。

示例代码

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

Animal.prototype.sayHi = function() {
  console.log('Hi, I am ' + this.name);
}

function Cat(name) {
  Animal.call(this, name);
}

Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;

var cat = new Cat('Tom');
cat.sayHi(); // Hi, I am Tom

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程