作用域
# 作用域
定义:一套用于确定何处以及何处查找变量的规则。
[TOC]
# 一、查询
# 1.1 LHS查询
查找用来对变量进行赋值
非严格模式:如果在全局作用域中无法找到目标变量,则会在全局作用域中创建具有该名称的变量。
严格模式:不创建全局变量,只返回ReferenceError异常。
# 1.2 RHS查询
获取变量的值
找不到变量就抛出ReferenceError错误
查询到变量,但对变量的值进行了不合理的操作,则抛出TypeError错误
# 1.3 小练习
function foo(a) {
var b = a;
return a+b;
}
var c = foo(2);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
LHS查询有3处:c=...; a=2(隐式变量分配);b=...
RHS查询有4处:foo(2); =a; a...; b...
- 编译器有话说:当变量出现在赋值操作的左侧时进行 LHS 查询,出现在右侧时进行 RHS 查询。
- 讲得更准确一点, RHS 查询与简单地查找某个变量的值别无二致,而 LHS 查询则是试图找到变量的容器本身,从而可以对其赋值。
- 从这个角度说, RHS 并不是真正意义上的“赋值操作的右侧”, 更准确地说是“非左侧”。
# 二、作用域
域:空间、范围、区域……
作用:读、写
- script是域
- 全局变量、全局函数
- 自上而下(单线程)
- 函数是域
- 局部域
- {}是域
# 2.1 词法作用域(lexical scoping)
- 在定义时确定,就是写代码的时候。
- 不在乎何时何地被调用,只关心函数被声明时所处的位置。
# 2.2 动态作用域(dynamic scoping)
- 在调用时确定,就是代码运行的时候。
- 不在乎如何声明以及在任何处声明的,只关心何处调用。
# 2.3 浏览器
JS解析器:先编译后执行
# 2.3.1 编译器
执行第一步:找一些东西,但不会读取。JS预解析。
# 2.3.2 引擎
执行第二步:逐行解读代码。
表达式:= + - * / % ++ -- ! 参数……
表达式可以修改预解析的值!函数声明不会改变预解析的值