我们知道 JS 有对象,比如
var obj = { name: 'obj' }
image.png
我们会发现 obj已经有几个属性(方法)了。那么问题来了:valueOf/toString/constructor 是怎么来?我们并没有给 obj.valueOf 赋值呀。
上面这个图有点难懂,手画一个示意图:
image.png
我们发现控制台打出来的结果是:
obj本身有一个属性 name (这是我们给它加的)
obj还有一个属性叫做 proto(它是一个对象)
obj还有一个属性,包括 valueOf, toString, constructor等
obj.__proto__其实也有一个叫做__proto__的属性(console.log没有显示),值为 null
现在回到我们的问题:obj 为什么会拥有 valueOf / toString / constructor 这几个属性?
答案: 这跟 __proto__有关 。
当我们「读取」 obj.toString 时,JS 引擎会做下面的事情:
看看 obj 对象本身有没有 toString 属性。没有就走到下一步。
看看 obj.__proto__ 对象有没有 toString 属性, 发现 obj.__proto__ 有 toString 属性, 于是找到了,所以 obj.toString
实际就是第2步中找到的 obj.__proto__.toString。
如果 obj.__proto__没有,那么浏览器会继续查看 obj.__proto__.__proto__。
如果 obj.__proto__.__proto__ 也没有,那么浏览器会继续查看 obj.__proto__.__proto__.__proto__。
5.直到找到 toString 或者 __proto__ 为 null。
上面的过程,就是「读」属性的「搜索过程」。而这个「搜索过程」,是连着由 proto 组成的链子一直走的。这个链子,就叫做「原型链」。
网友评论