搞懂 JavaScript 的难点 —— 原型

757 阅读2分钟

三个重要知识

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 是所有对象的原型 ObjectFunction 构造出来的 所以,Function 构造了 Object.prototype 推论,Function 才是万物之源啊!

错在哪

Object.prototypeObject.prototype 对象的区别,虽然Object.prototype是Function构造出来的,但是Object.prototype对象不是Function构造出来的。 对象里面从来都不会包含另一个对象 接下来我们要把 JS 世界的建造顺序理清楚

JS世界的构造顺序

  1. 创建根对象 #101(toString),根对象没有名字
  2. 创建函数的原型 #208(call /apply),原型 __proto__ 为 #101
  3. 创建数组的原型 #404(push/pop),原型 __proto__ 为 #101
  4. 创建 Function #342,原型 __proto__ 为 #208__
  5. 用 Function.prototype 存储函数的原型,等于 #208
  6. 此时发现 Function 的 __proto__ 和 prototype 都是 #208
  7. 用 Function 创建 Object
  8. 用 Object.prototype 存储对象的原型,等于 #101
  9. 用 Function 创建 Array
  10. 用 Array.prototype 存储数组的原型,等于 #404
  11. 创建 window 对象
  12. 用 window 的 'Object' 'Array' 属性将 7 和 9 中的函数命名
  13. 记住一点,JS 创建一个对象时,不会给这个对象名字的

image-20210501170626427.png

  1. new Object() 创建 obj1

  2. new 会将 obj1 的原型 __proto__设置为 Object.prototype,也就是 #101

  3. new Array() 创建 arr1

  4. new 会将 arr1 的原型 __proto__ 设置为 Array.prototype,也就是 #404

  5. new Function 创建 f1

  6. new 会将 f1 的原型 __proto__ 设置为 Function.prototype,也就是 #208

  7. 自己定义构造函数 Person,函数里给 this 加属性

  8. Person 自动创建 prototype 属性和对应的对象 #502

  9. 在 Person.prototype #502 上面加属性

  10. 用 new Person() 创建对象 p

  11. new 会将 p 的原型 __proto__ 设为 #502

image-20210501211603251.png

Object.prototype的原型是什么?

image-20210501212703990.png

Function.prototype的原型是什么?

image-20210501213003313.png

var f = () => {}f的原型是什么?

image-20210501215357008.png

Function的原型是什么?

image-20210501215929100.png

Array.prototype.toString的原型是什么?

image-20210501222344306.png

Object的原型是什么?

image-20210501222517405.png