不同原型继承方式之间的区别可以通过以下代码示例来解释:
function Parent() {
this.name = 'Parent';
}
Parent.prototype.sayHello = function() {
console.log('Hello from Parent');
};
function Child() {
this.age = 10;
}
Child.prototype = new Parent();
var child = new Child();
console.log(child.name); // 输出: Parent
child.sayHello(); // 输出: Hello from Parent
原型链继承是将父类的实例作为子类的原型,通过Child.prototype = new Parent()
将Parent的实例赋值给Child的原型。这种方式的缺点是共享了父类实例的属性和方法,当子类实例修改了这些属性时,会影响到其他子类实例。
function Parent() {
this.name = 'Parent';
}
Parent.prototype.sayHello = function() {
console.log('Hello from Parent');
};
function Child() {
Parent.call(this);
this.age = 10;
}
var child = new Child();
console.log(child.name); // 输出: Parent
child.sayHello(); // 报错: child.sayHello is not a function
构造函数继承是通过在子类构造函数中调用父类构造函数来继承属性,但无法继承父类原型上的方法。
function Parent() {
this.name = 'Parent';
}
Parent.prototype.sayHello = function() {
console.log('Hello from Parent');
};
function Child() {
Parent.call(this);
this.age = 10;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
var child = new Child();
console.log(child.name); // 输出: Parent
child.sayHello(); // 输出: Hello from Parent
组合继承是结合了原型链继承和构造函数继承的方式。通过在子类构造函数中调用父类构造函数继承属性,并将父类的实例作为子类的原型继承方法。这种方式既能继承父类的属性和方法,又能避免共享属性的问题。
function createObject(obj) {
function F() {}
F.prototype = obj;
return new F();
}
var parent = {
name: 'Parent',
sayHello: function() {
console.log('Hello from Parent');
}
};
var child = createObject(parent);
console.log(child.name); // 输出: Parent
child.sayHello(); // 输出: Hello from Parent
原型式继承是通过一个中间函数createObject
返回一个以传入对象为原型的新对象来实现继承。这种方式可以继承传入对象的属性和方法,但无法实现多继承。
function createObject(obj) {
var clone = Object.create(obj);
clone.sayHello = function() {
console.log('Hello from Parent');
}
return clone;
}
var parent = {
name: 'Parent'
};
var child = createObject(parent);
console.log(child.name); // 输出: Parent
child.sayHello(); // 输出: Hello from Parent
寄生式继承是在原型式继承的基础上,添加了自定义的属性和方法。这种方式可以根据需要在继承对象上添加额外的属性和方法。
通过以上代码示例,可以看到不同原型继承方式之间的区别和各自的特点。在选择继承方式时,需要根据具体的需求和设计考虑使用哪种方式。