基本概念
1995诞生
- 借鉴C语言的基本语法
- 借鉴Java的数据类型和内存管理
- 借鉴Scheme语言,函数为第一等公民(可以作为参数、返回值,可以赋值给变量)
- 借鉴Self语言,使用基于原型的继承机制
1、浏览器模型
-
Browser进程
-
GPU进程
-
渲染进程
- GUI线程(与js线程互斥)
- JS线程(单线程)
- 事件触发线程
- 定时器触发线程
- 网络线程
-
插件、网络进程
JS基础
动态(弱类型)语言:运行时才能确定数据的类型const、var、let
面向对象、函数式 解释类语言、JIT 安全:不能对本地数据进行操作
安全:在浏览器中执行,不访问内部的系统
性能差:边解释边运行
2、数据类型
复杂类型: 存储对象的类型,包括数组、函数等
基础类型: String、Undefined、Number、Null、Boolean + Symbol、Bigint
复杂的数据类型原始值可以被改变,基础数据类型不可以被改变
3、作用域
4、变量提升
- let、const没有变量提升,提前访问会报错
- var有变量提升,提前访问返回Undefined
- function可以先调用再定义(提升了整个函数)
- 赋值给变量的函数无法提前调用
func is not a function
JS是怎么运行的
jit就是优化代码,一段代码出现两次以上,会转为机器码存储起来
执行上下文
JS引擎解析到可执行代码片段时先做一些执行前的准备工作
- 全面执行上下文:代码开始执行时创建,压入执行栈栈底,每个生命周期只有一份
- 函数执行上下文:编译函数代码时生成变量环境、词法环境等,函数执行结束的时候该执行环境从栈顶弹出
创建执行上下文
绑定this 创建词法环境 创建变量环境
词法环境:const 函数 let的变量
变量环境:放var的变量
outer:指向外部变量环境的一个指针
ESP:记录当前执行状态的指针
进阶知识
1、闭包
函数体运行完毕,但是函数的闭包没运行完,则函数的变量等会继续存在,等待调用
闭包内容会在getName结束后回收
2、this
-
普通函数的this指向windows
-
对象调用函数中的this指向对象
call apply bind 可以改变this指向
-
构建函数中的this
- 创建临时对象
- 将this指向临时对象
- 执行构造函数
- 返回临时对象
3、垃圾回收
栈的垃圾回收
ESP指针弹到下一个节点,原节点变成无效内存,后面会被其他数据覆盖
堆的垃圾回收
-
新生代空间:分为对象区域(放活跃的对象)和空闲区域,空间较小,存储较小的新变量
- 垃圾标记 把对象区域的垃圾标记出来
- 对象复制 把对象区域里没被标记的复制到空闲区域
- 区域反转 对象区域转成空闲区域,原空闲区域转成对象区域
-
老生代空间:较大的变量或活跃的变量,仅一个区域
- 垃圾标记 标记垃圾
- 清除垃圾
- 碎片区域整合 把原来是垃圾的空闲碎片区域整合成大片区域
4、事件循环
运行顺序从上到下
- 同步任务:优先级从上到下
- 微任务:完成微任务,再完成微任务产生的微任务才能运行下一个,then()可以产生微任务。微任务队列先于宏任务执行
- 宏任务:按队列完成所有宏任务,后面可以跳转去运行宏任务产生的微任务,计时器可以产生宏任务,队列按计时器完成的先后排列