JS继承与工厂构造及原型设计模式详解
什么是继承?
继承是指一个对象直接使用另一个对象的属性和方法。在JavaScript中,对象可以通过继承原型链上的属性和方法。
继承的方式
JavaScript中实现继承的方式有以下几种:
1. 原型链继承
原型链继承是指将父类的实例作为子类的原型。实现方式如下:
function Parent() {
this.name = 'Parent name';
}
Parent.prototype.getName = function() {
return this.name;
}
function Child() {}
Child.prototype = new Parent();
var child = new Child();
console.log(child.getName()); // Parent name
原型链继承存在的问题是:当我们给子类的原型中添加一个引用类型的属性时,这个属性会被所有子类实例共享,且可能导致数据的误修改。
2. 借用构造函数继承
借用构造函数继承是指在子类构造函数中通过apply或call方法调用父类的构造函数。实现方式如下:
function Parent(name) {
this.name = name;
}
function Child(name) {
Parent.call(this, name);
}
var child = new Child('Child name');
console.log(child.name); // Child name
借用构造函数继承的优势是可以传参,并且通过子类实例修改引用类型的属性不会影响其它实例。
借用构造函数继承的缺点是不能继承父类原型链上的属性和方法。
3. 组合继承
组合继承是指将原型链继承和借用构造函数继承结合起来使用。实现方式如下:
function Parent(name) {
this.name = name;
}
Parent.prototype.getName = function() {
return this.name;
}
function Child(name, age) {
Parent.call(this, name);
this.age = age;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
Child.prototype.getAge = function() {
return this.age;
}
var child = new Child('Child name', 10);
console.log(child.getName());
console.log(child.getAge());
组合继承是继承中最常用的方式,它既可以继承父类构造函数中的属性,也可以继承原型链上的属性和方法,缺点是调用了两次父类构造函数。
4. 原型式继承
借助原型可以基于已有的对象创建新的对象,可以达到类似于继承的效果。实现方式如下:
var parent = {
name: 'Parent name',
getName: function() {
return this.name;
}
}
var child = Object.create(parent);
child.name = 'Child name';
console.log(child.getName()); // Child name
在原型式继承中,引用类型的属性共享问题存在,也就是说,修改一个子类实例上的引用类型属性会影响其它实例。
5. 寄生式继承
寄生式继承的基本思路是创建一个新对象,然后将该对象作为参数传入一个封装的函数中,在函数内部增强该对象,最后返回这个对象。实现方式如下:
function createChild(parent) {
var child = Object.create(parent);
child.sayHello = function() {
console.log('Hello');
}
return child;
}
var parent = {
name: 'Parent name',
getName: function() {
return this.name;
}
}
var child = createChild(parent);
child.name = 'Child name';
console.log(child.getName());
child.sayHello(); // Hello
寄生式继承与原型式继承一样,无法避免引用类型共享的问题。
6. 寄生组合式继承
寄生组合式继承是组合继承的优化版,通过构造函数继承避免了调用两次父类构造函数的问题。实现方式如下:
function Parent(name) {
this.name = name;
}
Parent.prototype.getName = function() {
return 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.getAge = function() {
return this.age;
}
var child = new Child('Child name', 10);
console.log(child.getName());
console.log(child.getAge());
工厂构造模式
工厂构造模式是一种通过工厂方法创建对象的方式。实现方式如下:
function createObject(name) {
var obj = new Object();
obj.name = name;
obj.sayHello = function() {
console.log('Hello');
}
return obj;
}
var obj = createObject('Object name');
obj.sayHello();
工厂构造模式可以通过多次调用工厂方法来创建多个相同结构的对象。缺点是对象无法识别,即无法通过instanceof运算符来确定对象的类型。
原型设计模式
原型设计模式是一种通过将方法挂载至原型对象上的方式来创建对象的方式。实现方式如下:
function Person() {}
Person.prototype.name = 'Person name';
Person.prototype.sayHello = function() {
console.log('Hello');
}
var person1 = new Person();
var person2 = new Person();
console.log(person1.name);
console.log(person2.name);
person1.sayHello();
原型设计模式可以通过将同样的方法集中在原型对象上,从而避免了多次赋值方法的操作。同时,原型对象上的方法是可以被子类继承使用的。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS继承与工厂构造及原型设计模式详解 - Python技术站