javascript 杂记
Windows 下手动安装 (Volta)[https://volta.sh/]
- 去 Volta 的 (GitHub Releases)[https://github.com/volta-cli/volta/releases] 下载含二进制文件的压缩包
- 解压后将
volta.exe
、volta-shim.exe
、volta-migrate.exe
添加至PATH
- 运行
volta setup
,接着前往%LOCALAPPDATA%\Volta\bin
,将上一步的volta-shim.exe
复制五份到这里,并分别重命名为node.exe
、npm.exe
、npx.exe
、yarn.exe
、pnpm.exe
命名约定
javascript style guide
变量
- 小驼峰命名
- 前缀应为名词
- 尽量体现变量类型
常量
- 全体大写
- 使用下划线分割单词
函数
- 小驼峰
- 前缀应为动词
- 部分常见前缀约定:
can
判断执行权限,返回布尔has
判断是否包含,返回布尔is
判断是否为,返回布尔get
获取值,返回对应值set
设置值,无返回、返回布尔、返回链式对象load
加载数据,无返回、返回布尔
类与构造函数
- 大驼峰
- 前缀为名称
类成员
- 公有成员使用通常命名
- 私有成员带
_
作为前缀
注释
行内注释
1 | code; // 评论注释 |
单行注释
1 | code; |
多行注释
1 | /* |
方法与函数注释
1 | /** |
- 作为JSDoc的一部分
- 部分常用关键字:
@param {类型} 形参名 - 描述
@return {类型} 描述
@exemple 示例代码
事件冒泡与捕获
事件冒泡与捕获是为了解决页面中事件流(事件发生顺序)的问题,例如:
如果父子元素都会在同一个事件发生时触发回调则:
- 冒泡事件会从最内层的元素开始发生,一直向上传播
- 捕获事件会从最外层开始发生,直到最具体的元素
根据冒泡特性,我们可以进行事件委托(event delegation),将事件绑定在父级元素上,通过Event.target
获得子元素
运行机制
JS引擎
:将代码转为机器语言执行JSRuntime
:暴露出 APIJS 宿主环境
(JS 运行时
(JS 引擎
)) 层层包含
引擎
是单线程的,一个时间点只有一个函数被调用,
内存栈
负责实际值的存储
调用栈 ECS Execution Context Stack
负责逻辑执行 LIFO
(后进先出),引擎将代码分为多个 可执行上下文
(EC Execution Context),压入执行栈
- Global:全文上下文
- Function:函数上下文
- Eval:Eval 函数上下文
-
入口文件全部代码作为
IIFE
(立即执行匿名函数)入栈,为全局EC
;进入EC
时填充声明,执行时给予具体值 -
运行过程中若有函数,则将其作为
局部EC
入栈 -
运行完后出栈
EC
可以看作一个对象:1
2
3
4
5
6
7
8
9EC = {
VO: {
/* 变量对象,存储函数arguments对象、参数、变量、声明 */
},
this: {},
Scope: {
/* 作用域,包含VO以及所有父EC的VO */
},
};-
VO
:函数形参(Arguments)、函数声明(FD Function Declaration)、变量声明(VD)存储于此VO
:全局对象(Global Object)AO
:活动对象(Active Object)进入函数EC
时创建
-
作用域链
(Scope):是对EC
中的变量对象VO
和AO
有序访问的链表,能够帮助访问到其中存放的变量和函数的定义
-
Web APIs
当引擎需要事件循环
进行异步操作时,调用栈会将操作分发给其他模块——这里
一般是多线程的,用于处理各种事件
Callback queue
回调队列,FIFO
(先进先出),当 Web API 完成异步操作时,会将结果和回调函数放入队列
Event Loop
不断检查调用栈与回调队列,将回调队列内的任务不断插入调用栈,实现回调
另有轮询、事件等用于异步操作
虚拟 DOM
直接操作DOM
十分复杂,使用一个相对简单“替代品”(比如 JavaScript 对象)操作,然后再转换为真实DOM
,这个“替代品”即为虚拟DOM
然而更新真实DOM
是十分耗费资源的,如果仅仅是局部更新,将整个 DOM 重新渲染是不可取的,于是我们将新旧虚拟DOM
进行比较,求出他们间的差异,只更新真实DOM
的这一部分即可
求差异是一种编辑距离
问题