JS作用域

所有内容均不是原创,单纯之前学习时做的笔记。内容结合了非常多的文章视频,已经记不清参考的哪里的了,所以就没有加参考说明了。

作用域

作用域是什么?

简单来说,作用域 指程序中定义变量的区域,它决定了当前执行代码对变量的访问权限,在JS中可分为全局作用域和函数作用域。

作用域有什么特点?

  1. 声明提前:一个声明在函数体内都是可见的某函数优先于变量
  2. 非匿名自执行函数,函数变量为只读状态,无法修改

作用域内部原理是什么?

  1. 编译

    • 过程就是编译器把程序分解成词法单元,将词法单元解析成AST(抽象语法树),再把AST转换成机器指令等待执行得过程
  2. 执行

    • 引擎运行时会首先查询作用域,在当前的作用域集合中是否存在一个叫作a的变量。如果是,引擎就会使用这个变量;如果否,引擎会继续查找该变量。
    • 如果引擎最终找到了变量a,就会将2赋值给它。否则引擎会抛出一个异常
  3. 查询

    • 引擎查询分为LHS查询和RHS查询,RHS查询与简单地查找某个变量的值没什么区别,而LHS查询则是试图找到变量的容器本身,从而可以对其赋值
  4. 嵌套

    • 在当前作用域中无法找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量,或抵达最外层的作用域(也就是全局作用域)为止。
  5. 异常

    • RHS

      1. 如果RHS查询失败,引擎会抛出ReferenceError(引用错误)异常
      2. 如果RHS查询找到了一个变量,但尝试对变量的值进行不合理操作,比如对一个非函数类型值进行函数调用,或者引用null或undefined中的属性,引擎会抛出另外一种类型异常:TypeError(类型错误)异常
    • LHS

      1. 当引擎执行LHS查询时,如果无法找到变量,全局作用域会创建一个具有该名称的变量,并将其返还给引擎。
      2. 如果在严格模式中LHS查询失败时,并不会创建并返回一个全局变量,引擎会抛出同RHS查询失败时类似的ReferenceError异常

作用域链是什么?

当可执行代码内部访问变量时,会先查找本地作用域,如果找到目标变量即返回,否则会去父级作用域继续查找...一直找到全局作用域。我们把这种作用域的嵌套机制,称为作用域链

什么是词法作用域?

词法作用域就是定义在词法阶段的作用域,是由写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变。

自由变量是什么?

在当前作用域中存在但未在当前作用域中声明的变量叫自由变量。