01 js的基本概念
浏览器多进程:Browser进程、GPU进程、渲染进程、插件进程、网络进程
渲染进程:GUI线程、JS线程、事件触发线程、定时器触发线程、网络线程
GUI线程、JS线程是互斥的
js是动态弱类型语言
- js不是纯面向对象也不是纯函数式语言
- 函数式:参数 ----> 结果
- 副作用(状态变化、网络请求)、纯函数(在任意的时间点传入相同的参数能够得到相同的结果)
问题:js是单纯解释类语言?是解释一行执行一行吗?
- 是有编译的过程的,因为有函数提升和变量提升,不是一行一行的顺序执行的
- 所以js不是纯的解释执行语言,也是经过编译的
安全:因为js执行需要宿主环境:浏览器,不能访问本地的文件系统之类的
性能差:边解释边执行,相对于编译型语言性能会比较差
- 复杂数据类型和基本数据类型的区别:存储位置不同
- 复杂数据类型的原始值是可以被改变的,但是基本数据类型的原始值是不能被改变的
- 作用域:变量的可访问性和可见性
- js是静态作用域,也被称为词法作用域
02 js是怎么执行的
- AST:抽象语法树
- 执行上下文
- 中间有字节码的原因:字节码的代码量比机器码少,节约内存的开销。去执行的时候再把字节码转化为机器码去执行
- JIT:对字节码进行优化,相同的代码出现2次及以上,v8就会认为其是弱代码(多次出现的代码),会直接把这部分转化为机器码,再去存储起来,下次再遇到,就直接转化为机器码,不需要转化为字节码,直接执行输出结果,提高了执行速度
--- token --- AST
- 执行上下文:执行前的准备工作
- 执行上下文:变量环境、词法环境、this、可执行代码
- 分类:全局执行上下文、函数执行上下文
- 调用栈有限制:2千多
- 递归太深了可以改为迭代法
this和执行上下文绑定的
- 词法环境:函数声明和let、const
- 变量环境:var
- outer:指向外部变量环境的一个指针,注意是外部,而不是前一个
-
作用域链
- ESP:记录当前执行状态的指针
03 js的进阶知识点
- 创建闭包,闭包是一个地址,地址指向堆内存上的一块内存
- 这块内存保存的是闭包访问的变量
- 闭包可能会导致内存泄漏
- 闭包本质是没有被回收的对象
- 普通函数嵌套,还是指向window
- new的时候做了什么?
- 垃圾回收分为堆和栈
- 栈的垃圾回收:ESP指针
- 堆的垃圾回收:分代回收
- 新生代(小的变量)(副垃圾回收机制,对象区域放活跃的)、老生代(数据的来源:如果占用内存很大的变量;新生代经过了2轮垃圾回收还没有被回收掉就放到老生代垃圾回收中)(标记清除,内存整理)(主垃圾回收器)
- 在做标记清除的时候,js引擎是停顿的,全停顿
- 解决办法:把任务拆分成小的碎片任务来处理
- js是单线程的,只有一个线程在执行js
- 有异步任务,有两个任务队列
- 定时器线程、事件触发线程
- 写0的话,最小的是4ms
04 课程总结
- 1.JS是单线程的,但是Render进程里面有多个线程
- 2.JS线程和GUI线程互斥,执行大的计算任务会导致页面卡顿
- 3.基础数据类型存在栈上,复杂数据类型存在堆上
- 4.const、let没有变量提升,提前使用会报错
- 5.JS也有编译的过程,执行之前会生成执行上下文
- 6.一个执行上下文包括变量环境、词法环境、this
- 7.变量环境里面有一个指向外部函数执行上下文的指针,形成了作用域链
- 8.全局执行上下文只有一份
- 9.this和执行上下文绑定