发布于 2024 年 2 月 26 日,星期一
JavaScript作用域深度剖析的核心在于理解变量的可见性和生命周期,从局部作用域到全局作用域的过渡揭示了代码执行时的变量查找机制。局部作用域受限于函数或块级结构,变量仅在定义范围内有效,避免全局污染。全局作用域则涵盖整个脚本,变量无处不在,需谨慎使用以防止命名冲突。闭包通过保留外部作用域的引用,实现局部变量的持久化。理解作用域链的构建和变量提升现象,有助于编写更清晰、可维护的代码。
系列首发于公众号『非同质前端札记』https://mp.weixin.qq.com/s?__biz=MzkyOTI2MzE0MQ==&mid=2247485576&idx=1&sn=5ddfe93f427f05f5d126dead859d0dc8&chksm=c20d73c2f57afad4bbea380dfa1bcc15367a4cc06bf5dd0603100e8bd7bb317009fa65442cdb&token=1071012447&lang=zh_CN#rd ,若不想错过更多精彩内容,请“星标”一下,敬请关注公众号最新消息。
JavaScript
事实上是一门编译语言
。var a = 2;
// 分解后:
var、a、=、2、;
// 空格是否会被当做词法单元,取决于空格在这门语言中是否具有意义。
有状态
还是无状态
的方式进行的。简单来说,任何 JavaScript 代码片段在执行前都要进行编译(通常就在执行前)
引擎
:从头到尾负责整个 JavaScript 程序的编译及执行过程。编译器
:引擎的好朋友之一,负责语法分析及代码生成等脏活累活。作用域
:引擎的另一个好朋友,负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实行一套严格的规则,确定当前执行的代码对这些标识符的访问权限。var a = 2;
这段代码是一句声明。但会经过编译器和引擎的处理来进行。LHS和RHS
LHS: 赋值操作的目标是谁
RHS: 谁是赋值操作的源头
function foo(a) {
var b = a;
return a + b;
}
var c = foo(2);
// 对话:
1. 声明 var c
2. 对 c 进行 LHS
3. 对 foo(2) 进行 RHS
4. function foo(a) 期间会进行 a = 2, 对 a 进行 LHS
5. 声明 var b
6. 对 b 进行 LHS
7. 对 a 进行 RHS
8. return a + b; 分别对 a、b 进行 RHS
// 答案:
1. 所有的 LHS(一共有3处)
1. c =..;
2. a = 2(隐士变量分配)
3. b = ..
2. 所有的 RHS (一共有4处)
1. foo(2..
2. = a;
3. a..
4. .. b
作用域是根据名称查找变量的一套规则
。当一个块或函数嵌套在另一个块或函数中时,就会发生作用域的嵌套
。因此在当前作用域中无法找到某个变量时,引擎就会在外层作用域中继续查找,直到找到该变量,或抵达最外层的作用域(也就是全局作用域)为止。// 非严格模式下
function foo(a) {
console.log(a + b);
}
var a = 2;
foo(2); // 4
// 严格模式下:
function foo(a) {
console.log(a + b);
}
var a = 2;
foo(2); // 4
引擎会从当前的执行作用域中开始查找变量,如果找不到就会向上一级中继续查找。当抵达最外层的全局作用域时,无论找到还是没找到,查找的过程都会停止。
// 非严格模式下:
function foo(a) {
console.log(a + b);
b = a;
}
foo(2); // 4
// 严格模式下:
'use strict';
function foo(a) {
console.log(a + b);
b = a;
}
foo(2); // ReferenceError: b is not defined
ReferenceError
'。ReferenceError
异常。"严格模式"(use strict)
,在行为上有很多不同,其中一个不同的行为就是严格模式下禁止自动或隐式地创建全局变量
。因此在严格模式中引擎执行 LHS 查询失败时,并不会创建一个全局变量,而是直接抛出一个 ReferenceError
。null
或 undefined
类型的之中属性,那引擎则会抛出另外一种类型的异常 TypeError。
ReferenceError
同作用域判断失败相关,而 TypeError
代表作用域判别成功了,但对结果的操作是非法或不合理的。LHS 和 RHS
LHS: 赋值操作的目标是谁
= 操作符
在调用函数时的形参会导致关联作用的赋值操作。也就是说 foo (a, b, c...), 都会有 a = xxx, b = xxx, c = xxx ...... 的行为。RHS: 谁是赋值操作的源头
ReferenceError
异常。"严格模式"(use strict)
,在行为上有很多不同,其中一个不同的行为就是严格模式下禁止自动或隐式地创建全局变量
。因此在严格模式中引擎执行 LHS 查询失败时,并不会创建一个全局变量,而是直接抛出一个 ReferenceError
。null
或 undefined
类型的之中属性,那引擎则会抛出另外一种类型的异常 TypeError。
ReferenceError
同作用域判断失败相关,而 TypeError
代表作用域判别成功了,但对结果的操作是非法或不合理的。Q:(question)
R:(result)
A:(attention matters)
D:(detail info)
S:(summary)
Ana:(analysis)
T:(tips)