知识点
基本概念
- 内存
- 变量
- 数据类型
- 对象
控制语句
- if else
- for
对象
- 原型、原型链
- 对象分类
- new 一个新对象
- 构造函数
- this 的隐式传递和显式传递
难点
JS三座大山
- 原型
- this
- AJAX
重要总结
JS公式
- 对象.proto === 其构造函数.prototype
- 推理出函数公理
根公理
- Object.prototype 是所有对象的(直接或间接)原型
函数公理
- 所有函数都是由 Function 构造的
- 任何函数.proto === Function.prototype
- 任意函数有 Object / Array / Function
- 结合JS公式理解
常见混乱
乱一
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 是间接原型
举例
数组属性展开,数组._ proto _ 为Array.Prototype,即Array.Prototype为数组的直接原型
上图Array.Prototype展开,其原型为Object.prototype,所以Object.prototype是数组的间接原型
图解
- 类比
- 父、子、孙,
- 企业架构,总经理、部门经理、部门职员
乱三
Object.prototype 不是根对象
理由
- Object.prototype 是所有对象的原型
- Object 是 Function 构造出来的
- 所以,Function 构造了 Object.prototype
- 推论,Function 才是万物之源啊!
错误点
- Object.prototype 是根对象的地址
- Object.prototype对象 是具体指根对象那个对象
- 根对象整体不在Object里面,只是地址在里面
- Function构造了Object,没有构造那个对象,他只是构造了根对象的地址
构建JS世界
JS 世界的构造顺序
- 创建根对象 #101(toString),根对象没有名字
- 创建函数的原型 #208(call /apply),原型 __p 为 #101
- 创建数组的原型 #404(push/pop),原型 __p 为 #101
- 创建 Function #342,原型 __p 为 #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 创建一个对象时,不会给这个对象名字的
JS 世界的构造顺序(续)
- 用 new Object() 创建 obj1
- new 会将 obj1 的原型 __p 设置为 Object.prototype,也.就是 #101
- 用 new Array() 创建 arr1
- new 会将 arr1 的原型 __p 设置为 Array.prototype,也就是 #404
- 用 new Function 创建 f1
- new 会将 f1 的原型 __p 设置为 Function.prototype,也就是 #208
JS 世界的构造顺序(续)
- 自己定义构造函数 Person,函数里给 this 加属性
- Person 自动创建 prototype 属性和对应的对象 #502
- 在 Person.prototype #502 上面加属性
- 用 new Person() 创建对象 p
- new 会将 p 的原型 __p 设为 #502
图示
总结
构造函数
- 是用来构造对象的
- 会预先存好对象的原型,原型的原型是根
- new 的时候将对象的 __p 指向原型
对象
- 所有对象都直接或间接指向根对象
- 如果对象想要分类,就在原型链上加一环
- 用构造对象可以加这一环