浅谈JavaScript的几种继承实现方式
JavaScript是一种支持面向对象编程的语言,也支持多种继承实现方式。本文将介绍JavaScript中几种常见的继承实现方式,以及它们的优缺点。
1. 原型链继承
原型链继承是JavaScript最基本、最常见的继承方式。通过让子类原型指向父类实例,从而实现子类继承父类的属性和方法。
实现方式
function Parent() {
this.name = 'parent';
this.names = ['parent1', 'parent2'];
}
Parent.prototype.sayName = function() {
console.log(this.name);
}
function Child() {
this.name = 'child';
}
Child.prototype = new Parent(); // 原型链继承
const child1 = new Child();
console.log(child1.name); // "child"
child1.sayName(); // "child"
console.log(child1.names); // ["parent1", "parent2"]
优缺点
- 优点:简单易懂,容易实现;
- 缺点:
- 父类构造函数中的引用类型属性会被所有子类实例共享;
- 无法实现多继承;
2. 借用构造函数
又称为经典继承,通过调用父类的构造函数来实现子类继承父类的属性和方法,从而避免了原型链继承中子类实例共享父类引用类型属性的问题。
实现方式
function Parent() {
this.names = ['parent1', 'parent2'];
}
function Child() {
Parent.call(this); // 借用 Parent 的构造函数
this.name = 'child';
}
const child1 = new Child();
console.log(child1.name); // "child"
console.log(child1.names); // ["parent1", "parent2"]
优缺点
- 优点:
- 避免了原型链继承中父类引用类型属性被所有子类实例共享的问题;
- 可以在子类构造函数中向父类传递参数;
- 缺点:
- 方法都在构造函数中定义,新建实例时都会创建一次,无法实现复用;
- 无法实现函数复用,父类原型上的方法无法被子类调用;
3. 组合继承
组合继承即将原型链继承与借用构造函数组合起来,通过子类构造函数中调用父类构造函数,实现子类实例继承父类构造函数中定义的属性和方法,通过子类原型指向父类实例实现子类实例继承父类原型上定义的属性和方法。
实现方式
function Parent(name) {
this.name = name;
this.colors = ['red', 'green', 'blue'];
}
Parent.prototype.sayName = function() {
console.log("My name is " + this.name);
}
function Child(name, age) {
Parent.call(this, name); // 借用 Parent 的构造函数
this.age = age;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
Child.prototype.sayAge = function() {
console.log("I'm " + this.age + " years old.");
}
const child1 = new Child('Tom', 18);
child1.colors.push('yellow');
console.log(child1.colors); // ["red", "green", "blue", "yellow"]
child1.sayName(); // "My name is Tom"
child1.sayAge(); // "I'm 18 years old."
优缺点
- 优点:
- 既可以实现原型链继承,又可以避免父类引用类型属性被子类实例共享;
- 可以在子类构造函数中向父类传递参数;
- 父类原型上的方法可以复用;
- 缺点:父类构造函数在子类原型上执行了一次,导致子类实例的构造函数会多执行一次。
4. ES6 Class
ES6中提供了class关键字,可以更加简洁、直观地实现继承,并且支持继承多个类。
实现方式
class Parent {
constructor(name) {
this.name = name;
this.colors = ['red', 'green', 'blue'];
}
sayName() {
console.log("My name is " + this.name);
}
}
class Child extends Parent {
constructor(name, age) {
super(name); // 调用父类的构造函数
this.age = age;
}
sayAge() {
console.log("I'm " + this.age + " years old.");
}
}
const child1 = new Child('Tom', 18);
child1.colors.push('yellow');
console.log(child1.colors); // ["red", "green", "blue", "yellow"]
child1.sayName(); // "My name is Tom"
child1.sayAge(); // "I'm 18 years old."
优缺点
- 优点:
- 语法简洁,易读易懂;
- 支持多继承(extends后可以跟多个父类);
- 缺点:无法实现动态继承。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈JavaScript的几种继承实现方式 - Python技术站