JS总结

63 阅读3分钟

第一个重要知识:JS 公式

  • 对象.proto === 其构造函数.prototype

  • JS 唯一公式,如果不会就套公式

第二个重要知识:根公理

  • Object.prototype 是所有对象的(直接或间接)原型

  • 加了一个直接或间接,所谓公理就是规定好的

第三个重要知识:函数公理

  • 所有函数都是由 Function 构造的

  • 任何函数.__proto__ === Function.prototype

  • 任意函数有 Object / Array / Function

拨乱反正

乱一

  • XXX 的原型

{name:'frank'} 的原型

[1,2,3] 的原型

Object 的原型

  • 解读 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 是间接原型

image.png

乱三

  • Object.prototype 不是根对象
  • 理由: Object.prototype 是所有对象的原型

Object 是 Function 构造出来的

所以,Function 构造了 Object.prototype (错误! Function只是构造了一个存根对象地址的属性,仅此而已)

推论,Function 才是万物之源啊!

  • 错在哪: Object.prototypeObject.prototype 对象 的区别

对象里面从来都不会包含另一个对象

接下来我们要把 JS 世界的建造顺序理清楚

image.png

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 创建一个对象时,不会给这个对象名字的

JS 世界的构造顺序(续)

  1. 用 new Object() 创建 obj1 new 会将 obj1 的原型 __proto__ 设置为 Object.prototype,也就是 #101

  2. 用 new Array() 创建 arr1 new 会将 arr1 的原型 __proto__ 设置为 Array.prototype,也就是 #404

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

JS 世界的构造顺序(续)

  1. 自己定义构造函数 Person,函数里给 this 加属性 Person 自动创建 prototype 属性和对应的对象 #502

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

  3. 用 new Person() 创建对象 p new 会将 p 的原型 __proto__ 设为 #502

image.png

总结

  • 构造函数

是用来构造对象的

会预先存好对象的原型,原型的原型是根

new 的时候将对象的 __proto__ 指向原型

  • 对象 所有对象都直接或间接指向根对象

如果对象想要分类,就在原型链上加一环

用构造函数可以加这一环

  • 思考 如果加了一环之后,想再加一环怎么办

以后会在「继承」里讲