一般情况下,我们可以使用以下方式实现 JavaScript 中的继承:
1.原型继承
可以通过设置父类(原型对象)为子类原型的方式实现继承。在子类原型中添加属性和方法,在子类实例中调用即可得到继承效果。
例如:
function Parent() { this.name = 'parent'; } Parent.prototype.sayName = function() { console.log(this.name); } function Child() { this.name = 'child'; } // 将Child的原型设置为Parent实例化的对象,实现继承 Child.prototype = new Parent(); Child.prototype.constructor = Child; var child = new Child(); child.sayName(); // 输出:child
2.构造函数继承
在子类中调用父类的构造函数,使用 call() 或 apply() 方法将父类的作用域赋给子类,使得子类得到父类的属性和方法。缺点是无法继承父类原型中的属性和方法。
例如:
function Parent() { this.name = 'parent'; } Parent.prototype.sayName = function () { console.log(this.name); }; function Child() { Parent.call(this); this.childName = 'child'; } var child = new Child(); console.log(child.name); // 输出:parent console.log(child.childName); // 输出:child child.sayName(); // 报错,sayName 不是 Child 的方法
3.组合继承
组合继承结合了原型继承和构造函数继承的优点。通过将父类的构造函数赋给子类,实现了父类属性的继承,通过将父类的原型对象赋给子类原型对象,实现了父类方法的继承。
例如:
function Parent() { this.name = 'parent'; } Parent.prototype.sayName = function() { console.log(this.name); } function Child() { Parent.call(this); this.childName = 'child'; } Child.prototype = new Parent(); // 继承父类原型上的方法 Child.prototype.constructor = Child; var child = new Child(); console.log(child.name); // 输出:parent console.log(child.childName); // 输出:child child.sayName(); // 输出:child
4.寄生组合式继承
在组合继承的基础上,将父类原型对象赋给一个临时构造函数的原型对象,然后将子类的原型对象指向该临时构造函数的实例对象原型,最后将子类原型对象的 constructor 指向子类构造函数。
例如:
function Parent() { this.name = 'parent'; } Parent.prototype.sayName = function() { console.log(this.name); } function Child() { Parent.call(this); this.childName = 'child'; } // 创建一个临时的构造函数,将父类的原型对象赋给该临时构造函数的原型对象 function ObjectCreate(prototype) { function F() {} F.prototype = prototype; return new F(); } Child.prototype = ObjectCreate(Parent.prototype); Child.prototype.constructor = Child; var child = new Child(); console.log(child.name); // 输出:parent console.log(child.childName); // 输出:child child.sayName(); // 输出:child