导读 作用域是用来声明,访问和修改变量的上下文,定义了变量的访问权限和查找机制。

作用域分类:

  • 全局作用域 (整个JS运行环境,最顶层作用域,其声明的函数、变量等都是全局的)
  • 函数作用域 (函数执行时会创建作用域)
  • 块级作用域 ({ }大括号在 let、const关键字特性产生的作用域)

JS属于编译语言,逐行执行;编译的过程分为三部分:

      分词/词法分析。
      解析/把词法分析转换成AST(抽象语法树)。
      代码生成/把AST转成可执行代码。

示例:

var a = 1; 

编译过程:

      分成var a、a=1;两部分进行分析。
      查看当前作用域是否有a,如果有就忽略,如果没有就创建变量a。
      (var、function声明的变量会在当前作用域下进行变量提升)
      赋值操作,首先查看当前作用域下是否有变量a,要是不存在变量a就会报错,要是存在进行赋值;其次如果是作用域嵌套的情况,当前作用域下不存在变量a,就会向外层作用域查找,直到全局作用域,如果不存在变量a就会报错。

执行过程:

      执行var a语句进行查找a变量,这个过程叫做LHS(左侧为查找目标)。
      执行a = 1赋值操作,过程叫做RHS(右侧为目标查找的目的)。
      进行RHS必然会进行LHS。

注意:取值和赋值都是RHS,变量声明和形参是LHS;RHS和LHS发生在执行过程中。

示例:

function foo(a) {
    var b = a;
    return a + b
}
var c = foo(2)

3处LHS查询:

      var c 声明
      var b 声明
      形参 a 声明

4处RHS查询:

      foo(2) 取值foo并执行
      var b = a语句,取值a
      a + b语句,取值a
      a + b语句,取值b

用var声明的变量会进行变量提升,提升到当前作用域的最顶部,其值是undefined,因此在变量前进行取值不会报错。
非严格模式下对没有用var关键字声明的变量语句之前进行RHS,报ReferenceError异常。如果是之后进行RHS,会先进行LHS,如果当前作用域还是全局作用域下都没有找到,会自动创建一个全局变量并返回,严格模式下LHR查询失败时,并不会创建一个全局变量并返回,报ReferenceError异常。
变量的访问权限问题:

块级作用域里的变量外层作用域是无法访问,变量是指由let,const。
函数的形参和变量,内部函数是外层作用域无法访问,属于局部变量。变量是指由let,const,var,function声明的。

原文来自:https://www.cnblogs.com/daveweiwei/p/13459146.html

本文地址:https://www.linuxprobe.com/scope-of-js.html编辑:薛鹏旭,审核员:逄增宝

Linux命令大全:https://www.linuxcool.com/

Linux系统大全:https://www.linuxdown.com/

红帽认证RHCE考试心得:https://www.rhce.net/