6

作用域(一)

 2 years ago
source link: https://segmentfault.com/a/1190000040951881
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

作用域(一)

发布于 今天 13:56

这段时间小编把两本js的经典图书看完了,一本是《深入理解JavaScript》,一本是《你不知道的JavaScript》。中间有些内容小编是根本没看懂,这次小编决定看第二遍并和大家一起分享书中的内容,期待着和大家一起进步。
一、RHS和LHS
先看一个js中很常用的赋值语句

var a = 2;

在这个例子中,js的引擎会对变量a进行LHS查询,当然了,和这个相对应的是RHS查询。
那究竟什么是LHS和RHS呢,简单一点说,如果是对某个变量进行赋值,就是进行了一次LHS。获取一个变量的值,就进行了一次RHS。
说的更准确一点,RHS查询就是超着某个变量的值。而LHS查询则是试图找到变量的容器本身,然后对其赋值。
考虑以下代码:

console.log(a);

这段代码是对a的RHS引用,因为这里只是查询并取得a的值,并没有给a赋值。然后将取得的值传递给console.log
相比之后,下面这段代码就是对a的LHS引用,因为我们并不关心当前的a的值是什么,只是把2赋值给变量a

var a = 2;

了解了RHS和LHS,我们来看一个相对复杂的例子。

function foo(a){
    console.log(a) // RHS
}

foo(2). //LHS

二、作用域嵌套

我们知道,作用域是根据名称查找变量的一套规则。但在实际情况中,通常需要同时估计几个作用域。
当一个块或函数嵌套在另一个块或函数中的时候,就发生了作用域的嵌套。因此,在当前作用域中无法找到某个变量时,引擎就会在改作用域的外层嵌套作用域继续查找,直到找到改变量,或抵达最外层的作用域(全局作用域)为止。
考虑以下代码

fuction foo(a){
  console.log(a + b);
}
var b = 3;
foo(2); // 5

在这段代码中,对于函数foo,只接收一个参数a,对于变量b,在该函数作用域内并没有找到定义,于是引擎就会在外层作用域继续寻找,刚好,在全局作用域下,找到了var b = 3;然后将两个数字相加之后输出。
为了更形象,可以把作用域想象成一个高大的建筑
image.png
LHS和RHS引用都会在当前楼层进行查找,如果没有找到,就会坐电梯前往上一层楼,如果还是没有找到就继续向上,以此类推。一旦抵达顶层(全局作用域),可能找到了你所需的变量,也可能没找到,但无论如何查找过程都将停止。(小编理解这就是传说中的作用域链)如果在全局作用域都没找到该定义, 将会抛出异常。对于不同的情况,抛出的异常也会不一样,考虑以下代码。

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

foo(2);

第一次对b进行RHS查询时是无法找到该变量的。也就是说,这是一个“未声明”的变量,因为在任何相关的作用域中都无法找到它。包括全局作用域,也无法找到这个变量。
如果RHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出ReferenceError异常。值得注意的是,ReferenceError是非常重要的异常类型。相较之下,当引擎执行LHS查询时,如果在顶层(全局作用域)中也无法找到目标变量,全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎,前提是程序运行在非“严格模式”下。
如果RHS查询找到了一个变量,但是你尝试对这个变量的值进行不合理的操作,比如试图对一个非函数类型的值进行函数调用,或者引用null或undefined类型的值中的属性,那么引擎会抛出另外一种类型的异常,叫作TypeError。ReferenceError同作用域判别失败相关,而TypeError则代表作用域判别成功了,但是对结果的操作是非法或不合理的。
鉴于小编是第一次在公众号中把JavaScript往更深层次去研究,中间难免有错误或者理解上的失误,要是发现了,还请大家多多指出。小编愿意和大家在js这条路上共同进步。

参考文献:《你不知道的JavaScript(上)》


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK