JavaScript 中的继承是通过原型链实现的,这是一种基于原型的面向对象编程模型。每个 JavaScript 对象都有一个指向其原型的内部链接,原型本身也是一个对象,这样就形成了一个链式结构,称为原型链。
prototype
属性,这个属性指向一个对象,该对象包含可以被特定类型的所有实例共享的属性和方法。new
关键字调用构造函数创建的对象。null
)。call
或 apply
方法来继承父类的属性。以下是一个简单的原型链继承示例:
// 父类构造函数
function Animal(name) {
this.name = name;
}
// 父类原型上的方法
Animal.prototype.sayName = function() {
console.log('My name is ' + this.name);
};
// 子类构造函数
function Dog(name, breed) {
// 调用父类构造函数,继承属性
Animal.call(this, name);
this.breed = breed;
}
// 设置子类的原型为父类的实例,实现继承
Dog.prototype = Object.create(Animal.prototype);
// 修复子类构造函数的指向
Dog.prototype.constructor = Dog;
// 子类原型上的方法
Dog.prototype.sayBreed = function() {
console.log('My breed is ' + this.breed);
};
// 创建子类实例
var myDog = new Dog('Buddy', 'Golden Retriever');
// 调用继承的方法
myDog.sayName(); // 输出: My name is Buddy
myDog.sayBreed(); // 输出: My breed is Golden Retriever
问题:原型链继承中,父类构造函数会被调用多次,导致性能问题。
原因:在组合继承中,子类的原型被设置为父类的一个新实例,这会调用父类构造函数一次。然后在子类构造函数中又会调用父类构造函数一次。
解决方法:使用寄生组合式继承,只调用一次父类构造函数。
function inheritPrototype(subType, superType) {
var prototype = Object.create(superType.prototype); // 创建对象
prototype.constructor = subType; // 增强对象
subType.prototype = prototype; // 指定对象
}
// 父类构造函数
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log('My name is ' + this.name);
};
// 子类构造函数
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
// 实现继承
inheritPrototype(Dog, Animal);
Dog.prototype.sayBreed = function() {
console.log('My breed is ' + this.breed);
};
var myDog = new Dog('Buddy', 'Golden Retriever');
myDog.sayName();
myDog.sayBreed();
在这个例子中,inheritPrototype
函数帮助我们避免了重复调用父类构造函数的问题,从而提高了效率。
领取专属 10元无门槛券
手把手带您无忧上云