乐闻世界logo
搜索文章和话题

JavaScript 中的原型&原型链是怎么工作的?

浏览14
8月5日 12:52

JavaScript中的原型(prototype)和原型链(prototype chain)是其面向对象编程的基础。这两个概念是理解JavaScript中对象之间的关系和继承机制非常关键的部分。

原型(Prototype)

在JavaScript中,每一个函数创建时都会有一个名为 prototype的属性,这个属性是一个对象,它包含了可以由特定类型的所有实例共享的属性和方法。这意味着你可以使用原型来添加或者分享功能,而不需要在每个实例中重新定义这些功能。

例如,假设我们定义了一个构造函数:

javascript
function Person(name) { this.name = name; } Person.prototype.sayName = function() { console.log(this.name); };

以下是通过 Person构造函数创建的两个实例:

javascript
var person1 = new Person("Alice"); var person2 = new Person("Bob");

这里的 person1person2都没有自己的 sayName方法。当你调用 person1.sayName()时,JavaScript会查找 person1是否有这个方法。由于 person1没有,它会通过原型链查找 Person.prototype是否有 sayName方法。这样,person1person2实际上共享了 Person.prototype上的 sayName方法。

原型链(Prototype Chain)

原型链是JavaScript实现继承的机制。每个对象都有一个内部链接到另一个对象,即它的原型。这个原型对象本身也有一个原型,以此类推,直到某个对象的原型为 null。按照规范,null的原型没有原型,这通常被视为原型链的末端。

当你尝试访问一个对象的属性时,如果该对象本身没有这个属性,JavaScript引擎会沿着原型链向上查找,直到找到这个属性或者到达原型链的末端。

继续上面的例子,我们可以看到原型链是如何工作的:

javascript
person1.sayName(); // 输出: Alice
  1. 首先,JavaScript引擎检查 person1自身是否有 sayName属性。
  2. 发现 person1没有,引擎接着检查 person1的原型(即 Person.prototype)。
  3. Person.prototypesayName方法,所以这个方法被调用。

如果我们有一个对象的原型是另一个对象,那么第二个对象的属性和方法也可以被第一个对象访问。这个过程可以一直持续下去,形成了一个“链”。

通过原型链实现继承

我们可以使用原型链来实现继承。例如,如果我们有一个 Employee构造函数,它应该继承 Person

javascript
function Employee(name, title) { Person.call(this, name); // 继承属性 this.title = title; } Employee.prototype = Object.create(Person.prototype); Employee.prototype.constructor = Employee; Employee.prototype.sayTitle = function() { console.log(this.title); }; var employee1 = new Employee("Charlie", "Developer"); employee1.sayName(); // 输出: Charlie employee1.sayTitle(); // 输出: Developer

在这里,Employee.prototype被设置为一个新对象,这个新对象的原型是 Person.prototype。这样,Employee的所有实例都继承了 Person的方法。我们还修正了 Employee.prototype.constructor属性,确保它指向正确的构造函数。

通过上面的代码,我们创建了一个 Employee的实例 employee1,它能够调用继承自 PersonsayName方法,同时还有自己特有的 sayTitle方法。

标签:JavaScript