深入理解javascript之作用域
我所理解的作用域就是你所申明的变量、函数住在哪里?程序在需要的使用如何能够找到他们?而设计的这套规则即为作用域
而javascript是一门解释性语言,是在执行的前很短时间内编译再执行。
从以下方面来分析javascript的作用域
编译原理
词法分析: 将程序字符串分解一个一个独立的词法单元; 如下
var answer = 6 * 7;
拆分:var | answer | = | 6 | * | 7
语法分析:将词法数组转换成抽象的语法树AST[Abstract Syntax Tree]
代码生成: 将AST转换成可执行代码的过程称为代码生成
编译规则
- 遇到变量声明,优先询问作用域下是否存在一个该变量名称在同一个作用域集合中. 如果是,则忽略;否则在当前作用于集合中添加
- 遇到表达式执行【a=2】,引擎会优先询问作用域下是否存在此变量,如果是,引擎使用这个变量,如果否,则继续查找;如果找不到,则抛出引用错误异常
赋值的两个概念 LHS / RHS
-
RHS[retrieve his source value] LHS[]
-
LHS与RHS:javascript引擎的两种查找类型,含义是赋值操作的左侧与右侧。
-
LHS:对哪个赋值就对哪个进行LHS引用,可以理解为赋值操作的目标。
-
RHS:需要获取哪个变量的值,就对哪个变量的值进行RHS引用,理解为赋值操作的源头。
分析以下函数LHS与RHS个数
function foo(a){
var b=a;
rerurn a+b;
}
var c=foo(2);
为什么要引擎要使用两种查找类型?
处理方式不同; 非严格模式下,RHS对未声明的变量抛出现引用错误
词法作用域
作用域气泡
每个位置的作用域都会生成一个层级关系的气泡,引擎通过层级关系的气泡进行查找,直到查找就停止
遮蔽效应
最近的作用域气泡会遮蔽外部的作用域气泡里的变量
但全局作用域下的变量声明,可以通过window属性来访问 window.a
函数作用域和块作用域
函数作用域 【
IIFE (Immediately Invoked Function Expression)
UMD(Universal Module Definition)
】
IIFE (Immediately Invoked Function Expression)
(function(global){
...
...
})(window);
UMD(Universal Module Definition)
(function(global, def){
...
...
def(global);
})(window, function handler(window) {
...
...
} );
块作用域: 针对for if while代码块里`var`定义的变量或函数声明并不会只存在于块中
而用let来声明可以使生成块级作用域
声明提升
- 优先函数声明整体提升, 后来者会覆盖
- 变量声明整体提升
代码分享
for(var i =0 ;i < 10; i++ ) {
setTimeout(function() {
console.info(i);
}, 100);
}
for(let i =0 ;i < 10; i++ ) {
setTimeout(function() {
console.info(i);
}, 100);
}
如果觉得文章对您有用,请点下推荐。您的支持将鼓励我继续创作!