简单原型链继承
- 原理:将子类的原型对象的
__proto__
指向父类的原型对象,从而使子类的实例能够继承父类原型上的属性和方法。 - 示例:
function Parent() {
this.parentProperty = 'I am from Parent';
}
Parent.prototype.parentMethod = function() {
console.log('This is parent method');
};
function Child() {
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
const child = new Child();
console.log(child.parentProperty);
// 输出:I am from Parent,通过原型链继承了父类的属性
child.parentMethod();
// 输出:This is parent method,通过原型链继承了父类的方法
在上述示例中,Object.create(Parent.prototype)
创建了一个以Parent.prototype
为原型的新对象,并将其赋值给Child.prototype
,实现了简单的原型链继承。同时,需要手动将Child.prototype.constructor
指向Child
,以保证constructor
属性的正确性。
借用构造函数继承属性与原型链继承方法相结合
- 原理:通过在子类构造函数中使用
call
或apply
调用父类构造函数来继承父类的属性,再通过原型链继承父类的方法,这样既可以继承父类的属性,又可以避免子类实例共享父类实例的属性。 - 示例:
function Parent(name) {
this.parentProperty = 'I am from Parent, my name is ' + name;
}
Parent.prototype.parentMethod = function() {
console.log('This is parent method');
};
function Child(name) {
Parent.call(this, name);
this.childProperty = 'I am from Child';
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
const child = new Child('Bob');
console.log(child.parentProperty);
// 输出:I am from Parent, my name is Bob,通过借用构造函数继承了父类的属性
console.log(child.childProperty);
// 输出:I am from Child
child.parentMethod();
// 输出:This is parent method,通过原型链继承了父类的方法
在这个示例中,Parent.call(this, name)
在Child
构造函数中调用了Parent
构造函数,将父类的属性复制到了子类实例中。然后通过原型链继承了父类的方法,实现了更全面的继承方式。
寄生组合式继承
- 原理:这是一种更优化的继承方式,它通过一个中间对象来继承父类的原型对象,避免了在子类原型上直接继承父类实例带来的一些问题,同时结合借用构造函数继承属性,实现了高效且更符合面向对象设计原则的继承。
- 示例:
function Parent(name) {
this.parentProperty = 'I am from Parent, my name is ' + name;
}
Parent.prototype.parentMethod = function() {
console.log('This is parent method');
};
function Child(name) {
Parent.call(this, name);
this.childProperty = 'I am from Child';
}
function inheritPrototype(child, parent) {
const prototype = Object.create(parent.prototype);
prototype.constructor = child;
child.prototype = prototype;
}
inheritPrototype(Child, Parent);
const child = new Child('Bob');
console.log(child.parentProperty);
// 输出:I am from Parent, my name is Bob
console.log(child.childProperty);
// 输出:I am from Child
child.parentMethod();
// 输出:This is parent method
在寄生组合式继承中,inheritPrototype
函数创建了一个中间对象来继承父类的原型对象,并正确设置了constructor
属性,然后将子类的原型对象指向这个中间对象,实现了继承。这种方式在继承多个父类或需要更精细控制继承关系时非常有用,是一种较为推荐的继承方式。
使用__proto__
实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用class
和extends
关键字来实现更简洁和直观的继承语法,但理解基于__proto__
的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。