javascript|[[Prototype]] ——原型链两万字全面解析「建议收藏」

javascript|[[Prototype]] ——原型链两万字全面解析「建议收藏」

文章图片


[[Prototype

JavaScript 中几乎所有属性都有一个 [[Prototype

内置属性 , 其实就是一个对于其他对象的引用 。 几乎所有的对象都在创建时 [[Prototype

属性都会被赋予一个非空的值 。


JavaScript 中所有的对象都存在一个 [[Prototype

属性 , 而且它的 [[Prototype

是非空的 。
注意:我们很快就可以看到 , 对象的 [[Prototype

链接可以为空 , 虽然很少见 。

[[Prototype

一般是不为空的 , 但是可以人工的置为空 。
思考下面的代码:
var myObj = {
  a: 2


myObj.a  // 2


这段代码通过字面量的方式定义了一个对象 , 然后访问到了这个对象的属性 。 作者在这里拿出这个例子来 , 是想说明一般是不会访问到 [[Prototype

属性的 。
[[Prototype

引用有什么用呢?我们以前说过 , 当你试图访问一个对象的属性的时候会触发 [[Get

操作 , 比如 myObj.a 。 对于默认的 [[Get

操作来说 , 第一步是检查对象本身是否具有这个属性 , 如果有的话就使用它 。

这里的知识点是关于访问对象属性的时候 , 会触发对象的 [[Get

操作 , 这个方法是隐藏的 。
但是如果 a 不在 myObj 中 , 就需要使用对象的 [[Prototype

链了 。
对于默认的 [[Get

操作来说 , 如果无法在对象本身找到需要的属性 , 就会继续访问对象的 [[Prototype

链 。

这里提到了 [[Prototype

链 , 以及查找对象属性的方式 , 当对象本身并不具有某个属性的时候 , 就开始在 [[Prototype

链上查找 。
var anotherObj = {
  a: 2


var myObj = Object.create( anotherObj )
myObj.a //2

稍后我们会介绍 Object.create 的原理 , 现在只需要知道它会创建一个对象并把这个对象的 [[Prototype

关联到指定对象上 。

这段代码通过关联原型的方式 , 来进行属性的访问 , 可以看到  myObj 并没有指定任何属性 , 此时 a 属性是访问的原型链上的 anotherObj 的 a 属性 。
现在 myObj 对象的 [[Prototype

关联到 anotherObject 。 显然 myObj.a 并不存在 , 但是尽管如此 , 属性访问仍然成功地找到了值 2 。
但是 , 如果 anotherObj 中什么也不到 a 并且 [[Prototype

链不为空的话 , 就会继续查找下去 。
这个过程会持续找到匹配的属性名或者查找完整条 [[Prototype

链 。 如果是后者的话 ,[[Get

操作的返回值是 undefined 。
使用 for in 遍历对象时原理和查找 [[Prototype

链类似 , 任何通过原型链访问到的属性都会被枚举 。 使用 in 操作符来检查属性在对象中是否存在时 , 同样会查找对象整条原型链 , 无论属性是否可枚举 。

in 操作符作用于整条原型链 。 并且原型链的查找会在找到时就停止 , 找不到的话就持续到原型链的最后一层 。
in 操作符用来确定当前字符串的属性名是否存在于指定对象的原型链条上 。
var anotherObj = {
  a: 2
  b: 2


var myObj = Object.create( anotherObj )