JS 继承六种方式全面理解
2023-09-25 12:54:19
JavaScript 继承:全面指南
在软件开发中,继承是一种强大的机制,它允许我们创建新的对象,这些对象可以从现有的对象中继承属性和行为。JavaScript 提供了多种继承方式,每种方式都有其独特的优点和缺点。本文将全面探讨 JavaScript 中的继承,包括各种方法、其特点和优势,以及在不同情况下选择最合适方法的指导。
原型继承
原型继承是 JavaScript 中最基本、最直接的继承方式。它使用 Object.create()
方法创建一个新对象,并将其原型对象设置为另一个对象的原型对象。原型对象包含新对象将继承的属性和方法。
const parentObject = {
name: "John Doe",
age: 30
};
const childObject = Object.create(parentObject);
console.log(childObject.name); // John Doe
console.log(childObject.age); // 30
构造函数继承
构造函数继承是另一种常见的 JavaScript 继承方式。它使用 new
操作符创建新对象,并指定该新对象的构造函数。构造函数是一个函数,它将在创建新对象时被调用。
function Parent(name, age) {
this.name = name;
this.age = age;
}
function Child(name, age, school) {
Parent.call(this, name, age);
this.school = school;
}
const childObject = new Child("John Doe", 30, "Harvard University");
console.log(childObject.name); // John Doe
console.log(childObject.age); // 30
console.log(childObject.school); // Harvard University
组合继承
组合继承结合了原型继承和构造函数继承的优点,既保留了构造函数继承的属性独立性,又实现了原型链上的方法复用。
function Parent(name, age) {
this.name = name;
this.age = age;
}
Parent.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name);
};
function Child(name, age, school) {
Parent.call(this, name, age);
this.school = school;
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
const childObject = new Child("John Doe", 30, "Harvard University");
childObject.sayHello(); // Hello, my name is John Doe
console.log(childObject.name); // John Doe
console.log(childObject.age); // 30
console.log(childObject.school); // Harvard University
原型式继承
原型式继承是一种独特的 JavaScript 继承方式,它通过创建一个新对象,并将该新对象的原型对象设置为另一个对象的原型对象来实现继承。
const parentObject = {
name: "John Doe",
age: 30
};
const childObject = Object.assign(Object.create(parentObject), {
school: "Harvard University"
});
console.log(childObject.name); // John Doe
console.log(childObject.age); // 30
console.log(childObject.school); // Harvard University
寄生式继承
寄生式继承不涉及原型链,它通过创建一个新对象,并将另一个对象的属性和方法复制到该新对象来实现继承。
function Parent(name, age) {
this.name = name;
this.age = age;
}
function Child(name, age, school) {
const parentObject = new Parent(name, age);
parentObject.school = school;
return parentObject;
}
const childObject = Child("John Doe", 30, "Harvard University");
console.log(childObject.name); // John Doe
console.log(childObject.age); // 30
console.log(childObject.school); // Harvard University
寄生组合式继承
寄生组合式继承结合了寄生式继承和组合继承的优点,通过使用寄生式继承从父对象复制属性和方法,并使用组合继承从父对象继承原型链,实现继承。
function Parent(name, age) {
this.name = name;
this.age = age;
}
Parent.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name);
};
function Child(name, age, school) {
const parentObject = new Parent(name, age);
parentObject.school = school;
const childObject = Object.create(parentObject);
childObject.constructor = Child;
return childObject;
}
const childObject = Child("John Doe", 30, "Harvard University");
childObject.sayHello(); // Hello, my name is John Doe
console.log(childObject.name); // John Doe
console.log(childObject.age); // 30
console.log(childObject.school); // Harvard University
函数式继承
函数式继承是一种简单的 JavaScript 继承方式,它通过创建一个函数,并在该函数内部创建一个新对象并返回该对象来实现继承。
function Parent(name, age) {
return {
name: name,
age: age
};
}
function Child(name, age, school) {
const parentObject = Parent(name, age);
parentObject.school = school;
return parentObject;
}
const childObject = Child("John Doe", 30, "Harvard University");
console.log(childObject.name); // John Doe
console.log(childObject.age); // 30
console.log(childObject.school); // Harvard University
选择最合适的继承方式
选择最合适的 JavaScript 继承方式取决于具体的应用程序需求。
- 原型继承 适合需要简单、直接继承的情况。
- 构造函数继承 适合需要属性独立的情况。
- 组合继承 适合需要方法复用和属性独立的情况。
- 原型式继承 适合需要创建对象集合的情况。
- 寄生式继承 适合需要将属性和方法添加到现有对象的情况。
- 寄生组合式继承 适合需要从一个或多个对象继承属性、方法和原型链的情况。
- 函数式继承 适合需要快速、简单的继承情况。
常见问题解答
- 什么是 JavaScript 中的继承?
继承是一种机制,它允许创建新对象,这些对象可以从现有对象继承属性和行为。
- JavaScript 中有哪些不同的继承方式?
JavaScript 中有七种常见的继承方式:原型继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承和函数式继承。
- 哪种继承方式最适合我?
最合适的继承方式取决于应用程序的需求。没有一种继承方式是完美的,每一种方式都有其独特的优缺点。
- 如何在 JavaScript 中实现继承?
具体实现方式取决于所选的继承方式。有关详细信息,请参阅本文中的代码示例。
- 我可以同时使用多种继承方式吗?
可以,但要小心,因为这可能会导致代码复杂性和维护困难。