[nodejs 内功心法][作用域与闭包系列一] js作用域是什么?

作用域

作用域是一套规则,用于确定在何处以及如何查找变量。如果查找的目的是对变量进行赋值,那么就会使用LHS查询,如果目的是获取变量的值,就会使用RHS查询, 下面我们先了解一下 LHS 和 RHS

LHS

换句话说,当变量出现在赋值操作的左侧时进行 LHS 查询,出现在右侧时进行 RHS 查询。
LHS是要找到变量的内存地址,从而对其进行赋值

RHS

RHS查询与简单地查找某个变量的值别无二致, RHS就是要获取变量的值

不多逼逼,直接上代码吧。

function demo(a) {
	console.log(a);  // 100
}

demo(100)

上面这个例子里面既有LHS也有RHS, 我们来分析一下哪些是LHS, 哪些是RHS。
.
最后一行demo(…)函数的调用需要进行RHS引用,意味着去“找demo的值,并把它给我”
.
这里还有一个容易被忽略却非常重要的细节。
.
代码中隐式的 a=100 操作可能很容易被你忽略掉。这个操作发生在 100 被当作参数传递给 demo(…) 函数时,100 会被分配给参数 a。为了给参数 a(隐式地)分配值,需要进行一次 LHS 查询。
.
这里还有对 a 进行的 RHS 引用,并且将得到的值传给了 console.log(…)。console.log(…) 本身也需要一个引用才能执行,因此会对 console 对象进行 RHS 查询,并且检查 得到的值中是否有一个叫作 log 的方法。
.
最后,在概念上可以理解为在 LHS 和 RHS 之间通过对值 100 进行交互来将其传递进 log(…) (通过变量 a 的 RHS 查询)。假设在 log(…) 函数的原生实现中它可以接受参数,在将 100 赋值给其中第一个(也许叫作 arg1)参数之前,这个参数需要进行 LHS 引用查询。

作用域嵌套

当一个块或函数嵌套在另一个块或函数中时,就发生了作用域的嵌套。因此,在当前作用 域中无法找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量, 或抵达最外层的作用域(也就是全局作用域)为止。

function demo(a) {
	console.log( a + b );
}

var b = 2
demo(2) // 4

//对 b 进行的 RHS 引用无法在函数 foo 内部完成,但可以在上一级作用域(在这个例子中就 是全局作用域)中完成。
// 下面模拟引擎和作用域的对话
//引擎:foo 的作用域兄弟,你见过 b 吗?我需要对它进行 RHS 引用。 作用域:听都没听过,走开。
// 引擎:foo 的上级作用域兄弟,咦?有眼不识泰山,原来你是全局作用域大哥, 太好了。你见过 b 吗?我需要对它进行 RHS 引用。
// 作用域:当然了,给你吧。

遍历嵌套作用域链的规则很简单:引擎从当前的执行作用域开始查找变量,如果找不到, 就向上一级继续查找。当抵达最外层的全局作用域时,无论找到还是没找到,查找过程都 会停止。

为什么要区分LHS 和 RHS

因为在变量还没有申明(在任何作用域中都无法找到)的情况下,两种查询的行为是不一样的。

function demo(a) {
	console.log( a + b ); // 对b RHS查询无法找到变量 抛出ReferenceError错误
	b = a
}
demo(2);

上面的例子会抛出 ReferenceError 错误

重点

如果 RHS 查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出 ReferenceError 异常。值得注意的是,ReferenceError 是非常重要的异常类型。

相较之下,当引擎执行 LHS 查询时,如果在顶层(全局作用域)中也无法找到目标变量,全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎,前提是程序运行在非“ 严格模式”下。

作用域内心OS: “不,这个变量之前并不存在,但是我很热心地帮你创建了一个。”

ES5 中引入了“严格模式”。同正常模式,或者说宽松 / 懒惰模式相比,严格模式在行为上 有很多不同。其中一个不同的行为是严格模式禁止自动或隐式地创建全局变量。因此,在 严格模式中 LHS 查询失败时,并不会创建并返回一个全局变量,引擎会抛出同 RHS 查询 失败时类似的 ReferenceError 异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值