JavaScript实现继承的6种常用方式总结
本文主要介绍JavaScript实现继承的6种常用方式,包括原型链继承、构造函数继承、组合继承、寄生组合继承、ES6 class继承、Mixin继承。
1. 原型链继承
原型链继承是将子类的原型设置为父类的实例,通过原型链来实现继承。其实现步骤如下:
function Parent() {
this.name = 'parent';
}
Parent.prototype.sayHello = function() {
console.log('Hello from ' + this.name);
}
function Child() {}
Child.prototype = new Parent();
var child = new Child();
child.sayHello();
这种方式的缺陷是:所有子类实例共用一个父类实例,当修改某个子类实例中的属性时,其他子类实例的属性也会被修改。
2. 构造函数继承
构造函数继承是将父类的构造函数在子类中执行一遍,从而实现继承。其实现步骤如下:
function Parent(name) {
this.name = name;
}
Parent.prototype.sayHello = function() {
console.log('Hello from ' + this.name);
}
function Child(name) {
Parent.call(this, name);
}
var child = new Child('child');
child.sayHello();
这种方式的缺陷是:父类原型中的方法对于子类而言是不可见的。
3. 组合继承
组合继承是将原型链继承和构造函数继承结合起来,实现同时继承父类构造函数属性和原型上的方法。其实现步骤如下:
function Parent(name) {
this.name = name;
}
Parent.prototype.sayHello = function() {
console.log('Hello from ' + this.name);
}
function Child(name) {
Parent.call(this, name);
}
Child.prototype = new Parent();
var child = new Child('child');
child.sayHello();
这种方式的缺陷是:在调用两次父类构造函数,存在性能问题。
4. 寄生组合继承
寄生组合继承是在组合继承的基础上,通过优化避免了调用两次父类构造函数,其实现步骤如下:
function Parent(name) {
this.name = name;
}
Parent.prototype.sayHello = function() {
console.log('Hello from ' + this.name);
}
function Child(name) {
Parent.call(this, name);
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
var child = new Child('child');
child.sayHello();
这种方式是目前使用最多的继承方式,常用于大型项目中。
5. ES6 class继承
ES6 class继承是通过class和extends关键字实现继承,其实现步骤如下:
class Parent {
constructor(name) {
this.name = name;
}
sayHello() {
console.log('Hello from ' + this.name);
}
}
class Child extends Parent {
constructor(name) {
super(name);
}
}
var child = new Child('child');
child.sayHello();
逐渐取代了以前传统的继承方式,被广泛使用。
6. Mixin继承
Mixin继承是通过将多个对象混合在一起,实现继承。其实现步骤如下:
function mix(...mixins) {
class Mixin {
constructor() {
for (let mixin of mixins) {
copyProperties(this, new mixin());
}
}
}
for (let mixin of mixins) {
copyProperties(Mixin, mixin);
copyProperties(Mixin.prototype, mixin.prototype);
}
return Mixin;
}
function copyProperties(target, source) {
for (let key of Reflect.ownKeys(source)) {
if (key !== "constructor"
&& key !== "prototype"
&& key !== "name") {
let des = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, des);
}
}
}
class Parent {
constructor(name) {
this.name = name;
}
sayHello() {
console.log('Hello from ' + this.name);
}
}
class Child extends mix(Parent) {
constructor(name) {
super(name);
}
}
var child = new Child('child');
child.sayHello();
这种方式适用于需要组合多个对象的项目中。
示例说明:
// 寄生组合继承示例
function Shape(x, y) {
this.x = x;
this.y = y;
}
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.log('Shape moved.');
}
function Circle(x, y, r) {
Shape.call(this, x, y);
this.r = r;
}
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
Circle.prototype.getArea = function() {
return Math.PI * this.r * this.r;
}
var circle = new Circle(10, 10, 5);
console.log(circle.getArea());
circle.move(5, 5);
// ES6 class继承示例
class Shape {
constructor(x, y) {
this.x = x;
this.y = y;
}
move(x, y) {
this.x += x;
this.y += y;
console.log('Shape moved.');
}
}
class Circle extends Shape {
constructor(x, y, r) {
super(x, y);
this.r = r;
}
getArea() {
return Math.PI * this.r * this.r;
}
}
var circle = new Circle(10, 10, 5);
console.log(circle.getArea());
circle.move(5, 5);
以上代码分别演示了寄生组合继承和ES6 class继承的实现和使用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript实现继承的6种常用方式总结 - Python技术站