MENU

JavaScript 中 prototype 和 __proto__ 的区别

2021 年 06 月 16 日 • 阅读: 1574 • 英语

所以你在想 JavaScript 中 prototype__proto__ 的含义?它们不是完全相同的吗?让我们一起寻找答案。

对 prototype 的解释

苹果最近发布了它的新 iPhone,iPhone 11。这部手机有确定的特性 —— 例如,Face ID 和 4K 视频。生产的每部 iPhone 11 必须具有以上相同特性。

现在,让我们假定存在一个构造函数,每当被调用,它就生产一部新 iPhone 11。为了正确建造 iPhone 11,需要一台原型 —— 用来参考的 iPhone 11 模型。这份原型或模型确保每部 iPhone 11 都有 Face ID,能拍摄 4K 视频。因此,iPhone 构造函数必须知道并且能获得它要建造机器的原型。这就是构造器的 prototype 属性。

function iPhone() {}; // constructor

// a method for recognizing faces
iPhone.prototype.faceID = function() {};
// a method for taking 4k video
iPhone.prototype.video = function() {};

let newPhone = new iPhone(); // an iPhone 11

迄今为止都没有问题,对吧?接下来让我们进入 __proto__

prototype 与 __proto__ 的关系

我已经生产了一台 iPhone 11,把它存到了名为 newPhone 的变量中。newPhone 的内容看上去就像这样:

The contents of a new iPhone instance.

所以似乎新 iPhone 11 包含 Face ID 和 video!事实上,你可以执行 newPhone.faceID()newPhono.video(),它们都能正常工作。但是,为何这些特性被存储在名为 __proto__ 的对象上,而非直接作为 newPhone 的属性?

__proto__ 是每个类实例上的对象,指向创建它的 prototype。这儿,newPhone.__proto__iPhone.prototype 的引用,因此和后者持有相同的内容。通过包含一个和 iPhone.prototype 相同的 __proto__ 属性,newPhone 基本上在说,“看,既然我是一台 iPhone 11,我就具有其它任何 iPhone 11 一样的功能!我有 Face ID,4K 视频,和任何你能说出的功能。”

实际上,prototype__proto__ 唯一真实区别在于,前者是类构造器的属性,而后者是类实例的属性。换句话说,由于 iPhone.prototype 提供了一份构建 iPhone 的蓝图,newPhone.__proto__ 确认自己是根据那份特定蓝图构建的。至于这两个对象上的属性和方法,好吧,它们完全相同。

最后,你可能在想最后一行 __proto__: Object 的含义。这是因为 newPhone.__proto__ 实际上是一个 JavaScript 对象,JavaScript 对象也由特定 “蓝图” 构建而来。本例中,newPhone.__proto__.__proto__ 指向 Object.prototype,它是所有 JavaScript 对象的原型或蓝图。仅此而已!

延伸阅读

本文译自 medium,译者 LOGI

TG 大佬群 QQ 大佬群

返回文章列表 文章二维码
本页链接的二维码
打赏二维码