前面详细的解释了new的几个步骤,其中随意带过了一下原型链的概念,如果细读那篇文章,基本对原型也能有所理解。
原型有两个关键属性,一个是 __proto__ 一个是 prototype ,了解了这两个对象基本就能了解整个原型链的关系。
本篇主要探讨一下 __proto__ 这个属性。
javascript中几乎所有类型都拥有 __proto__ 这个属性,可以打印下面的 __proto__ 的值看看都是什么结果。
"字符串".__proto__
(123456).__proto__
(true).__proto__
(function(){}).__proto__
([]).__proto__
({}).__proto__
它们都有值,并且它们的值似乎告诉它们是什么,例如前面都有类型如 String 或 Boolean 或在直接放回该类型的字面量写法 function(){}; []; {}; ,那现在就假设 __proto__ 的用处就是说出它们是谁.。
再关注一点细节,这三个基本类型的 __proto__ 有一些相似,大概是这样的。
String {length: 0, [[PrimitiveValue]]: ""}
Number {[[PrimitiveValue]]: 0}
Boolean {[[PrimitiveValue]]: false} //以上出自chrome控制台
这三个值都是对象,展开它们会发现一些这种类型常用的属性,例如
length
match
toFixed
toString
它们都是什么鬼,难道在使用这些属性或方法的时候都是通过__proto__上找的,我只好假定 __proto__ 的作用是提供一些js原生的属性和方法,那么刚好就得出一个结论这些值原生的属性和方法都是从 __proto__ 来的。
接着往下走吧,还是不能理解 __proto__ ,但是大概了解了它的一些信息。
还发现一个规律, __proto__ 里面还有一个 __proto__ ,并且它们的值都是一样的并且是一个Object对象,这里又可以得出一个结论,这些数据类型通过 __proto__ 都会找到同一个Object对象。
再接下来插播一下null和undefined
为什么整篇都不见 undefined 和 null 这两个基友,而且当使用 undefined.__proto__ 和 null.__proto.__ 的时候会报错,说明这两个并没有这两个属性,但是在js中没有这个属性会返回 undefined ,那只能根据错误提示来参考,
Uncaught TypeError: Cannot read property '__proto__' of undefined
未知的类型错误,无法读取undefined的__proto__属性
也就是说这两个值不存在属性或方法的概念,它们本身就代表着无。
那么现在基本可以知道,在js中,只有两种类型,一种是有值类一种是无值类,有值类都可以通过 __proto__ 最终指向 Object 对象,而无值类就是 null 和 undefined 两种,一种代表空,一种代表未定义。
到了这里,大概明白了 __proto__ 是干什么的了,我并没有给它一个明确的定义,但是我可以简单的说一下它的功能:
- 除了 undefined 和 null 之外的所有值都有 __proto__ 这个值
- 这个 __proto__ 的值最终会指向同一个 Object 对象,例如 : 类似与这样查找最终会中找到 Object 对象: *.__proto.__.__proto.__.***__proto.__
- 某一个值的每一层的 __proto__ 中的方法都可以直接使用,例如: true.__proto__ 中有 toString 方法,那么就可以直接使用这个 true.toString() 方法,再例如 true.__proto.__.__proto.__ 中拥有 hasOwnProperty 这个方法,那么就直接可以使用 true.hasOwnProperty()