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的这一部分即可
求差异是一种编辑距离问题