三个重要知识
JS公式
对象.__proto__ === 其构造函数.prototype
根公理
Object.prototype
是所有对象的(直接或间接)原型
函数公理
所有函数都是由Function构造的
任何函数.__proto__ === Function.prototype
任意函数有 Object / Array / Function
拨乱反正
疑惑一
xxx 的原型
{name:'frank'} 的原型 //Object.prototype
[1,2,3] 的原型 //Array.prototype
Object 的原型 //Function.prototype
解读
Object
的原型是 Object.__proto__
:对
Object
的原型是 Object.prototype
:错
错在哪
「的原型」等价于「.__proto
__」
中文的「原型」无法区分 __proto__
和 prototype
所以我们只能约定,原型默认表示 __proto__
只不过__proto__
正好等于某个函数的 prototype
疑惑二
矛盾
[1,2,3]
的原型是 Array.prototype
你有说 Object.prototype
是所有对象的原型
那为什么 Object.prototype
不是 [1,2,3]
的原型
错在哪
原型分两种:直接原型和间接原型
对于普通对象来说,Object.prototype
是直接原型
对于数组、函数来说,Object.prototype
是间接原型
疑惑三
Object.prototype 不是根对象
理由
Object.prototype
是所有对象的原型
Object
是 Function
构造出来的
所以,Function
构造了 Object.prototype
推论,Function
才是万物之源啊!
错在哪
Object.prototype
和 Object.prototype
对象的区别,虽然Object.prototype
是Function构造出来的,但是Object.prototype
对象不是Function构造出来的。
对象里面从来都不会包含另一个对象
接下来我们要把 JS 世界的建造顺序理清楚
JS世界的构造顺序
- 创建根对象 #101(toString),根对象没有名字
- 创建函数的原型 #208(call /apply),原型
__proto__
为 #101 - 创建数组的原型 #404(push/pop),原型
__proto__
为 #101 - 创建 Function #342,原型
__proto__
为 #208__ - 用 Function.prototype 存储函数的原型,等于 #208
- 此时发现 Function 的
__proto__
和 prototype 都是 #208 - 用 Function 创建 Object
- 用 Object.prototype 存储对象的原型,等于 #101
- 用 Function 创建 Array
- 用 Array.prototype 存储数组的原型,等于 #404
- 创建 window 对象
- 用 window 的 'Object' 'Array' 属性将 7 和 9 中的函数命名
- 记住一点,JS 创建一个对象时,不会给这个对象名字的
-
用
new Object()
创建obj1
-
new
会将obj1
的原型__proto__
设置为Object.prototype
,也就是 #101 -
用
new Array()
创建arr1
-
new
会将arr1
的原型__proto__
设置为Array.prototype
,也就是 #404 -
用
new Function
创建 f1 -
new
会将f1
的原型__proto__
设置为Function.prototype
,也就是 #208 -
自己定义构造函数 Person,函数里给 this 加属性
-
Person 自动创建 prototype 属性和对应的对象 #502
-
在 Person.prototype #502 上面加属性
-
用 new Person() 创建对象 p
-
new 会将 p 的原型
__proto__
设为 #502
Object.prototype
的原型是什么?
Function.prototype
的原型是什么?
var f = () => {}
,f
的原型是什么?
Function
的原型是什么?
Array.prototype.toString
的原型是什么?
Object
的原型是什么?