JS总结
知识点
基本概念
内存、变量、数据类型、对象
控制语句
- if…else…
- for…
对象
- 原型、原型链
- 对象分类
- new一个新对象
- 构造函数
- this的隐式传递和显式传递
难点
JS三座大山
- 原型
- this
- AJAX
最重要的知识
JS公式
对象.__proto__===其构造函数.prototype
JS唯一公式,如果不会就套公式
根公理
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]的原型
其实
Array.prototype和Object.prototype都是[1, 2, 3]的原型。只不过一个是直接原型,一个是间接原型。
错在哪
- 原型分为两种: 直接原型和间接原型
- 对于普通对象来说,
Object.prototype是直接原型 - 对于数组、函数来说,
Object.prototype是间接原型
乱三
Object.prototype不是根对象
理由
Object.prototype是所有对象的原型Object是Function构造出来的- 所以,
Function构造了Object.prototype
其实是
Function构造了存Object.prototype(根对象)地址的这么一个属性,它并没有构造这个对象
- 推论,
Function才是万物之源呀
错在哪
Object.prototype(的地址)和Object.prototype对象的区别- 对象里面从来都不会包含另一个对象(它只会包含另一个对象的地址)
再画JS世界
上一版的JS世界: 内存图和 JS 世界
JS世界的构造顺序
- 创建根对象
#101(toString),根对象没有名字 - 创建函数的原型
#208(call/appy),原型__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对象(不属于JS世界)
- 用window的
'Object'``’Array’属性将7和9中的函数命名 - 记住一点,JS创建一个对象时,不会给这个对象名字的
JS世界的构造顺序(续)
如果要有一个新的对象,要做什么事情呢?
- 用
new Object()创建obj1 new会将obj1的原型__proto__设置为Object.prototype,也就是#101
Q: 为什么要设置为
Object.prototype?A: 因为我们在创建JS世界的时候,把原型的地址存在了这个上面
- 用
new Array()创建arr1 new会将arr1的原型__p设置为Array.prototype,也就是#404- 用
new Function创建f1 new会将f1的原型__proto__设置为Function.prototype,也就是#208
new什么,就把这个对象的原型设置成 什么的prototype.
JS世界的构造顺序(续)
- 自己定义构造函数Person,函数里给this加属性
- Person自动创建prototype属性和对应的对象
#502 - 在Person.prototype
#502上面加属性 - 用
new Person()创建对象p - new会将p的原型
__proto__设为#502
漂亮的图示
Object函数的prototype存储了根,就是对象的原型这么一个对象
每个函数存储了自己的原型,每个构造函数存储了它自己的对象的原型。

你品,你细品,你再自己好好细品。
总结
构造函数
- 是用来构造对象的
函数的构造函数构造出了函数,数组的构造函数构造出了数组,对象的构造函数构造出了对象
- 会预先存好对象的原型,原型的原型是根
new的时候将对象的__proto__指向原型
对象
- 所有对象都直接或间接指向根对象
- 如果对象想要分类,就在原型链上加一环
- 用构造对象可以加这一环
JS三大定理
结合JS三大定理来回答一下下面的这些问题
问题
Object.prototype的原型?
Object.prototype.__proto__ === null
Function.prototype的原型?
Function.prototype.__proto__ === Object.prototype
var f = ()=> {}的原型?
f.__proto__ = Function.prototype
Function的原型?
Function.__proto__ === Function.prototype
Array.prototype.toString的原型?
Array.prototype.toString.__proto__ === Function.prototype
Object的原型?
Object.__proto__=== Function.prototype
Array.prototype是什么东西的原型?
Array.prototype === [].__proto__