
JavaScript 原型继承
在本教程中,您将了解 JavaScript 原型继承的工作原理
在本教程中,您将了解 JavaScript 原型继承的工作原理。
JavaScript 原型继承简介
如果您使用过其他面向对象的编程语言(如 Java 或 C++),您就会熟悉继承概念。
在这种编程范式中,类是创建对象的蓝图。如果您希望新类重用现有类的功能,您可以创建一个扩展现有类的新类。这称为经典继承。
JavaScript 不使用经典继承。相反,它使用原型继承。在原型继承中,一个对象通过原型链接从另一个对象继承属性。
JavaScript 原型继承和 __proto__
让我们举个例子来说明这个概念。下面定义一个 person 对象:
let person = {
name: "John Doe",
greet: function () {
return "Hi, I'm " + this.name;
}
};在这个例子中,person 对象有一个属性和一个方法:
name是存储人名的属性。greet是一种以字符串形式返回问候语的方法。
默认情况下,JavaScript 引擎为您提供一个内置 Object() 函数和一个匿名对象,可以通过以下方式引用 Object.prototype:
请注意,圆圈代表一个函数,而正方形代表一个对象。
person 对象具有指向函数引用的匿名对象的链接Object()。代表[[Prototype]]联动:
这意味着 person 对象可以调用匿名对象定义的任何方法,通过匿名对象的引用 Object.prototype 。例如,下面展示如何通过 person 对象调用 toString() 方法:
console.log(person.toString());输出:
[object Object][object Object] 是对象的默认字符串表示形式。
当您通过 person 调用 toString() 方法时,JavaScript 引擎无法在 person 对象找到toString() 方法。因此,JavaScript 引擎遵循原型链并在 Object.prototype 对象中搜索方法。
由于 JavaScript 引擎可以在Object.prototype对象中找到 toString() 方法,因此它会执行 toString() 方法。
要访问 person 对象的原型,可以使用 __proto__ 属性。如下
console.log(person.__proto__);下面显示 person.__proto__ 和 Object.prototype 引用同一个对象:
console.log(person.__proto__ === Object.prototype); // true下面定义teacher 对象并且具有 teach() 方法:
let teacher = {
teach: function (subject) {
return "I can teach " + subject;
}
};与 person 对象一样,teacher.__proto__ 引用 Object.prototype 。如下图所示:
如果想让 teacher 对象访问 person 对象的所有方法和属性,可以像这样设置teacher 对象的原型引用 person 对象:
teacher.__proto__ = person;请注意,不要在生产代码中使用 __proto__ 属性。请仅将其用于演示目的。现在,teacher 对象可以通过原型链访问 person 对象的 name 属性和 greet() 方法:
console.log(teacher.name);
console.log(teacher.greet());输出:
John DoeHi, I'm John Doe当你在 teacher 对象调用 greet() 方法时,JavaScript 引擎首先在 teacher 对象搜索 greet() 方法。
由于 JavaScript引擎在 teacher 对象找不到 greet() 方法,它会沿着原型链搜索person 对象方法。
因为 JavaScript 引擎可以在 person 对象找到 greet() 方法,JavaScript 引擎它会执行方法。
在 JavaScript,我们说 teacher 对象继承 person 对象的方法和属性。而这种继承称为原型继承。
在 ES5 实现原型继承的标准方法
ES5 提供一种标准方法来处理原型继承,通过使用 Object.create() 方法。
请注意,现在您应该使用的 ES6class和extends关键字来实现继承。因为这要简单得多。
Object.create() 方法创建一个新对象并使用现有对象作为新对象的原型:
Object.create(proto, [propertiesObject])Object.create() 方法接受两个参数:
- 第一个参数
proto是用作新对象原型的对象。 - 第二个参数
propertiesObject是一个可选对象,它为新对象定义附加属性。
假设你有一个 person 对象:
let person = {
name: "John Doe",
greet: function () {
return "Hi, I'm " + this.name;
}
};下面创建一个空的 teacher 对象基于 person 对象的 __proto__ :
let teacher = Object.create(person);之后,您可以为 teacher 对象定义属性:
teacher.name = 'Jane Doe';
teacher.teach = function (subject) {
return "I can teach " + subject;
}或者您可以在一个语句中执行这些步骤,如下所示:
let teacher = Object.create(person, {
name: { value: 'John Doe' } ,
teach: { value: function(subject) {
return "I can teach " + subject;
}}
});ES5 还引入了 Object.getPrototypeOf() 返回对象原型的方法。例如:
console.log(Object.getPrototypeOf(teacher) === person);输出:
true结论
- 继承允许一个对象使用另一个对象的属性和方法,而无需复制代码。
- JavaScript 使用原型继承。












