js深入理解
01 js的基本理解
chrome浏览器进程
- Browser进程
- GPU进程
- 渲染进程
- GUI线程 把页面上的内容绘制出来
- JS线程 执行js线程
- 事件触发线程
- 定时器触发线程
- 网络线程
- 插件进程、网络进程...
JS的一些特性
-
单线程
在浏览器执行进程中只能同时执行一个进程,即当浏览器运行gui线程时js线程只能等待gui运行完毕才能继续运行
-
动态弱类型语言
动态弱类型语言即在声明变量时不用定义变量类型
静态强类型语言即在声明变量时需要定义变量类型
-
面向对象、函数式(是混用的)
其中函数式特性的部分就是 输入参数、接着输出结果
写react会有一些动态变化、网络请求都叫副作用,当调用函数时,除了返回函数值之外,还对主调用函数产生附加的影响。例如修改全局变量(函数外的变量)或修改参数
函数式有一些函数库jQuery、Ramda、loadsh
-
解释类语言、JIT
写一条编译一条
-
安全、性能差
js执行是需要附属环境的、需要浏览器,并不能做一些底层的操作
关于变量提升的点
02 JS是怎么执行的
为什么要先将抽象语法树转换成字节码 节省资源
JIT 什么是JIT 如果代码中多次出现重复代码,V8会将其判断为热代码,直接把他转换成机器码,下次遇见不在转换成自己码,直接转换成机器码。
执行上下文的生命周期包括三个阶段:创建阶段→执行阶段→回收阶段
- 全局执行上下文 — 这是默认或者说基础的上下文,任何不在函数内部的代码都在全局上下文中。它会执行两件事:创建一个全局的
window对象(浏览器的情况下),并且设置this的值等于这个全局对象。一个程序中只会有一个全局执行上下文。 - 函数执行上下文 — 每当一个函数被调用时, 都会为该函数创建一个新的执行上下文。每个函数都有它自己的执行上下文,不过是在函数被调用时创建的。函数上下文可以有任意多个。每当一个新的执行上下文被创建,它会按定义的顺序(将在后文讨论)执行一系列步骤。
- Eval 函数执行上下文 — 执行在
eval函数内部的代码也会有它属于自己的执行上下文,但由于 并不经常使用eval,所以在这里不作讨论。
词法环境:放函数声明和let、const定义的变量
变量环境:用来储存var变量
这里person是声明定义的obj(对象),其中赋予的是对象里内容在堆中存储的地址
js引擎中记录当前状态的指针ESP,当func执行上下文执行完之后,会指向全局,而func则成了无效内存,只有当func2执行的时候才会把func在栈内的内存空间替换掉
03 js的进阶知识
闭包
放回的是一个类似于函数的闭包
在闭包里面访问了dep和name就在栈内单独用一个内存存储访问的变量,而且这个闭包一直到showname即getname结束才会被回收,所以闭包的缺点是不容易被回收。
this指向
1.只要是普通函数中的this,无论是嵌套还是啥,都是指向windows
改他的this指向
js中的堆的垃圾回收
分为新生代空间和老生代空间(主回收站)
新生代中(分配一些变量比较小的;大的放在老生代)的垃圾回收步骤,对象区域放一些活跃的对象和变量数据,再将活跃的数据放在空闲区域,再将二者互换,再把对象区域中的数据清楚。
老生代空间中将一些垃圾数据内存标记清除之后,内存空间并不连续,所以会再进行一些内存整理,为了不全停顿,所以将这些任务分成一些碎片化任务,标记清楚一下,js再继续
事件循环
微任务先于宏任务
定时器线程是宏任务队列里面
promise会放在事件触发线程,是微任务