JS三座大山之 原型的简洁思路

356 阅读4分钟

JS世界

1.创造一个“对象的原型”

假设内存地址 #101

  • 也叫做“根”
  • 包含所有普对象的共有属性
  • “根”对象没有构造者,所以它没有原型 Object.prototype.__proto__ === null

2.创造一个“函数的原型”

假设内存地址 #202

  • 包含所有函数的共有属性
  • “函数的原型”对象是是由“根”对象创造的,所以: Function.prototype.__proto__ === Object.prototype

3.创造一个“数组的原型”

假设内存地址 #303

  • 包含数组的共有属性
  • “数组的原型”对象是由“根”对象创造的,所以: Array.prototype.__proto__ === Object.prototype

4.创造一个“函数的构造函数”Function

假设内存地址 #2020

Function的自身情况

  • 因为Function是一个构造函数,也就是说它是函数类型,
  • 函数都是由'Function'构造的,所以它具有所有函数的共有属性,即: Function.__proto__ === Function.prototype
  • Function.prototype 指向地址 #202,也就是“函数的原型”
  • 所以Function.proto 也指向地址 #202,“函数的原型”
  • 也就是说FunctionFunction自己构造的?
  • 具体不深入了

所有的新函数都由Function构造的

  • “函数的构造函数”Function,具有prototype属性
  • Function.prototype指向“函数的原型” 地址 #202
  • 并且,Function是“函数的构造函数”,所以,由它新构造的函数,都具有函数的共有属性
var fn =()=>{}
fn.__proto__ === Function.prototype
true

5.创造一个“对象的构造函数”Object

假设内存地址 #1010

Object的自身情况

  • 因为Object是一个构造函数,也就是说它是个函数类型;
  • 函数都是由Function构造的,所以它具有所有函数的共有属性: Object.__proto__ === Function.prototype
  • Function.prototype 指向地址 #202,也就是“函数的原型”
  • 所以Object.__proto__ 也指向地址 #202,“函数的原型”

所有的新对象都是由“Object”构造的(从阶段5以后)

  • “对象的构造函数”Object,具有prototype属性,
  • Object.prototype指向“对象的原型” 地址#101
  • 并且,Object是对象的构造函数,所以,由它新构造的对象都具有对象的共有属性: ({}).__proto__ === Object.prototype

6.创造一个“数组的构造函数”Array

假设内存地址是 #3030

Array的自身情况

  • 因为Array是一个构造函数,也就是说它是个函数类型;
  • 函数都是由Function构造的,所以Array具有所有函数的共有属性: Array.__proto__ === Function.prototype
  • Function.prototype 指向地址 #202,也就是“函数的原型”
  • 所以Array.__proto__ 也指向地址 #202,“函数的原型”

所有的新数组[]都是由Array构造的

  • 数组的构造函数Array,具有prototype属性,Array.prototype指向“数组的原型” 地址 #303
  • 并且,Array是数组的构造函数,所以,由它新构造的数组都具有数组的共有属性: [].__proto__ === Array.prototype

7,创建window对象(由浏览器提供,不属于JS)

  • window.Object属性,正式命名“对象的构造函数”为Object,之前的步骤中,Object名称只是为了方便说明
  • window.Array属性,正式命名“数组的构造函数”为Array,之前的步骤中,Array名称只是为了方便说明
  • 因为,JS创建一个对象时,是没有具体名称的,只有用一个具体的变量名称去引用时,它才有名称!

思路很简陋,未必全都正确;后续会继续完善,有异议可以提出,一定改正!

三个总结

1.JS公式

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

2.根公理

所有的对象都是由Object构造的,即Object.prototype是所有对象的(直接或间接的)原型

3.函数公理

一切函数都是Function构造的 函数.proto === Function.prototype 函数有Array、Object、Function

举例

乱一

{name:'frank'}的原型是什么?
({name:'frank'}).__proto__ === Object.prototype
true
  • {name:'frank'}是个对象,由Object new来的,所以它的原型是对象的原型
[1,2,3]的原型是什么?
[1,2,3].__proto__ === Array.prototype
true
  • [1,2,3]是个数组,由Array new来的,所以它的原型是数组的原型
Object的原型是什么?
Object.__proto__ === Function.prototype

  • Object是一个构造对象的构造函数,也就是函数,是由函数Function new来的,所以它的原型是函数的原型

乱二

[1,2,3]的原型疑惑

  • [1,2,3]的原型是Array.prototype
  • Object.prototype是所有对象的原型
  • Object.prototype为什么不是[1,2,3]的原型

解释

  • 原型分两种:直接原型和间接原型
  • 对于普通对象来说,Object.prototype是直接原型
  • 对于数组、函数这两个特殊类型的对象来说,Object.prototype是间接原型
//直接原型
[1,2,3].__proto__ === Array.prototype
true
//间接原型
Array.prototype.__proto__ === Object.prototype
true

乱三

1.Object.prototype的原型是什么?

Object.prototype.__proto__ === null
true
  • 对象的原型是“根”,所有没有构造者

2.Function.prototype的原型是?

Function.prototype.__proto__ === Object.prototype
true
  • 函数的原型是由“根”对象创造的,

3.函数f的原型是?

var f =()=>{}
undefined
f.__proto__ === Function.prototype
true

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

4.函数toString的原型是什么?

Array.prototype.toString.__proto__ === Function.prototype
true
  • 所有的函数都是由Function创造的