- 为什么JS这么强大,内容这么多,这个知识点学完还得学下一个知识点,这个知识点用到了还得去探索以为可能用不到的知识点或者
时间来不及不想去细细学习的知识点,好多好多!- 这篇文章主要在语法方面,对个人不太懂的语法部分进行梳理并给出自己的相应观点。
- 文章主要内容:
- JS是单线程的,但是Render进程里面有多个线程
- JS线程和GUI线程互斥,执行大的计算任务会导致页面卡顿
- 基础数据类型存在栈上,复杂数据类型存在堆上
- const、let没有变量提升,提前使用会报错
- JS也有编译的过程,执行之前会生成执行上下文
- 一个执行上下文包括变量环境、词法环境、this
- 变量环境里面有一个指向外部函数执行上下文的指针,形成了作用域链
- 全局执行上下文只有一份
- this和执行上下文绑定
- 关于解构语法和模板语法、模块用法的文档链接
JS运行基础
- JS不是纯的解释型语言,也是需要被编译的(eg,函数上下文,变量提升)
- 浏览器打开后,有Browser进程、GPU进程(显卡)、渲染进程(GUI线程(专门用来监听 GUI 的 特定线程,用于实现对 用户 在 图形用户界面上的 操作的监听和响应)/JS线程/事件触发线程/定时器触发线程/网络线程)、插件进程、网络进程……
- 变量类型:
- 基础数据类型:数字、字符串、bool、symbolJS(6).Symbol详细介绍_万人之英的博客-CSDN博客、bigintJS 基本数据类型之 BigInt 的知识点_bigint js_淘淘是只狗的博客-CSDN博客、undefined、null
- 复杂数据类型:对象(数组、函数,etc)
作用域
- 作用域:静态作用域,即变量的可访问性和可见性:
- 全局作用域
- 函数作用域
- 块级作用域
- 变量提升var:先使用变量稍后再声明变量而不会引发异常。JavaScript 变量感觉上是被“提升”或移到了函数或语句的最前面。但是,提升后的变量将返回 undefined 值。因此在使用或引用某个变量之后进行声明和初始化操作,这个被提升的变量仍将返回 undefined 值。
- let、const没有变量提升,提前访问会报错;function函数可以先调用再定义;赋值给变量的函数无法提前调用
- (重点,已掌握) 原型&原型链、promise链式调用、async/await 使用 Promise - JavaScript | MDN (mozilla.org)/async 函数 - JavaScript | MDN (mozilla.org)
- js源码——词法语法解析(执行上下文)——AST树(类似json的词法树)——Ignition字节码——turbofan/optimize或直接转为机器码
- 当JS引擎解析到可执行代码片段(通常是函数调用)的时候,就会先做一些执行前的准备工作,这个准备工作,就叫做"执行上下文(executioncontext简称EC)",也叫执行环境。
- 全局执行上下文:代码开始执行时就会创建,将他压执行栈的栈底,每个生命周期内只有一份
- 函数执行上下文:当执行一个函数时,这个函数内的代码会被编译,生成变量环境、词法环境等,
当函数执行结束的时候该执行环境从栈顶弹出(闭包无法将其返回函数弹出,会留在栈中等待进入老生代回收)。 - Eval执行上下文
- 上下文调用栈
- 创建执行上下文:
- 词法环境:基于ECMAScript代码的词法嵌套结构来定义标识符和具体本变量和函数的关联。一个词法环境由环境记录器和一个可能的引用外部词法环境的空值组成。
- 变量环境:变量环境和词法环境的一个不同就是前者被用来存储函数声明和变量(let和const)绑定而后者只用来存储var变量绑定。(堆空间)
- Outer(
作用域链):指向外部变量环境的一个指针 - this:
- 普通函数的this指向windows
- 对象内的方法调用this:对象调用指向对象;先赋值再调用,看调用的地方
- 类与对象(构造函数中调用this):创建临时对象;将this指向临时对象;执行构造函数;返回临时对象
- ESP(记录当前执行状态的指针)
垃圾回收
- 栈:ESP指针弹到下一个函数执行上下文
- 堆:分新生代与老生代
- 新生代
副垃圾回收器主要存放1M~8M变量,分对象区域与空闲区域,回收过程分三步:- 垃圾标记:对象区域中,标记活跃的变量和不活跃的变量
- 对象复制:将活跃的变量或对象放在空闲区域,不活跃的留在对象区域,
- 区域反转:将对象区域和空闲区域对换,清除掉对象区域。
- 老生代
主垃圾回收器主要是>8M内存的变量和经两次新生代回收未被回收的内存- 将碎片任务进行标记
- 清除标记的任务,剩余碎片
- 这个时候堆的内存呈碎片化,需要整理
- 停顿问题(标记清除全停顿)——碎片任务分别标记清楚
- 新生代
浏览器中JS事件循环
- node中也有事件循环,此处仅对浏览器客户端中js事件循环进行解析。
- JS是单线程的,microTask Queue(eg,promise、async、await)先进入event loop执行,然后macroTask Queue(浏览器内置API)进入event loop执行。
常见语法
React中提到的 JavaScript 主题的摘要:
写代码保持最新版本的 JavaScript 是一种很好的做法。