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__