原型链
原型链是JS中十分重要的一个概念,今天的文档就选这个主题(其实已经准备了好一会了这篇)
首先通过一张图来大概了解一下原型链
假设这是一个RPG游戏,在你创建人物的时候,可以选择创建一个角色并且指定传承了几代,传承二代的角色(变量X)将会在出生时获得一把剑和一个盾牌,而传承三代的角色(变量Y)将会在出生时获得一把剑,一个盾牌以及一个飞镖。
也许这张图初看之下有些懵逼,但不要着急,我们先往下看,看完之后再来回头看这张图。一定要回头看!!
什么时候需要讨论到原型链?
这里提供一段MDN站点上的释义,(用中文来读这个的时候,我总觉得很绕,捋不清__proto__和prototype下面提供一段中英双版本)
MDN上提供的中文版本:
当谈到继承的时候。
当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object)都有一个私有属性(称之为
__proto__)指向它的构造函数的原型对象(prototype)。
MDN上提供的英文版本(附逐句翻译):
When it comes to inheritance, JavaScript only has one construct: objects.
当谈到继承的时候,JS只有一种结构:对象。
Each object has a private property which holds a link to another object called its prototype.
每个对象都有一个私有属性,用于保持对另一个对象的链接,这个对象称为它的 prototype。
That prototype object has a prototype of its own, and so on until an object is reached with
nullas its prototype.这个作为prototype的对象也有一个自己的prototype,如此这般直到到达一个将
null作为它的prototype的对象。
什么是__proto__
以上,我们得到以下两点结论:
__proto__为对象的私有属性,顺着它一直到达null的这一过程称之为原型链(因为它由一个个原型链接而成)(a link to another object called its prototype)- 在这里我们还未得到属性
prototype的定义
什么是prototype
紧接上文,我们首先来解决属性prototype的定义问题。在不同的浏览器中,原型属性(__proto__)有不同的实现方式,一般的浏览器中我们能看到的原型属性被记为[[Prototype]]。即它们的含义是一样的。但是这区别于构造函数 func 的 prototype 属性。
关于构造函数的prototype属性,这是我在ECMAScript 1st Edition (ECMA-262)规范文档中得到的解释(附逐句翻译):
A prototype is an object used to implement structure, state, and behavior inheritance in ECMAScript.
原型是 ECMAScript用于实现结构、状态、行为继承的对象。
When a constructor creates an object, that object implicitly references the constructor’s associated prototype for the purpose of resolving property references.
当构造函数创建一个对象时,该对象隐式引用了构造函数的关联原型,用于解析属性引用。(PS:这一段我还有些似懂非懂)
The constructor’s associated prototype can be referenced by the program expression
constructor.prototype,[重点]构造函数的关联原型会被程序表达式
constructor.prototype引用and properties added to an object’s prototype are shared, through inheritance, by all objects sharing the prototype.
共享该原型的所有对象通过继承,共享添加到原型对象上的属性
而关于prototype属性的其他内容可以参看ECMA的相关文档。
以上,我们得到了这些结论:
prototype属性是Function的特有属性prototype属性会引用构造函数的关联原型prototype属性还包含其它一些内容
在浏览器控制台中一探
首先我们创建一个对象,基于继承的环境,我们使用new方式进行变量声明
const NUM = new Number(1);
然后观察一下这个NUM
也许你已经发现了,说好的__proto__属性没看到,关于这点请看以下解释:
遵循ECMAScript标准,
someObject.[[Prototype]]符号是用于指向someObject的原型。从 ECMAScript 6 开始,[[Prototype]]可以通过Object.getPrototypeOf()和Object.setPrototypeOf()访问器来访问。这个等同于 JavaScript 的非标准但许多浏览器实现的属性__proto__。但它不应该与构造函数
func的prototype属性相混淆。被构造函数创建的实例对象的[[Prototype]]指向func的prototype属性。Object.prototype属性表示Object的原型对象。
所以,只是虚惊一场,我们的探索之旅虽然遇到了[障眼法]。
当我们的脚步来到此处,请回想以下关键词,然后回去看文章一开始的那张图解。
继承
prototype(原型)
__proto__([[Prototype]])
prototype&&__proto__小结
function 拥有 prototype和__proto__
其他对象拥有__proto__
关于原型链就先写到这里,指正和补充请不吝赐教。
参考资料:
[MDN文档] developer.mozilla.org/zh-CN/docs/…
[网络博客] www.cnblogs.com/jayfeng/p/1…
\