ITPub博客

首页 > 应用开发 > Javascript > JavaScript深度理解——作用域

JavaScript深度理解——作用域

Javascript 作者:TT3310 时间:2020-10-24 10:17:39 0 删除 编辑

一、作用域是什么?

1. 编译原理

JavaScript是一门编译语言,而并不是通常所说的“动态”或“解释执行语言”。它不是提前编译的,编译结果也不能在分布式系统中进行移植。
编译语言执行之前的三个步骤:

1.分词/词法分析:

将由字符组成的字符串分解成有意义的代码块,这些代码块被称为词法单元。示例:var a = 3; 在这个过程中会分解成下面这些词法单元: var、a、=、3、; 。

2. 解析/语法分析:

将词法单元流(数组)转换成一个由元素逐渐嵌套所组成的代表了程序语法结构的树。这个树被称为“抽象语法树”(AST)。

3. 代码生成

将抽象语法树(AST)转化成可执行代码的过程。
JavaScript引擎不止上面的三个步骤,它的步骤要复杂得多。

注意:

  • JavaScript引擎不会用大量的时间来进行优化(相对于其他编译语言那么多的时间),因为JavaScript的编译过程不是发生在构建之前的。
  • JavaScript中大部分情况下编译发生在执行代码之前的几微秒,并且任何的JavaScript代码片段在执行前都会进行编译操作。

2. 理解作用域

谁参与JavaScript执行?

引擎: 从头到尾负责整个JavaScript程序的编译以及执行过程。
编译器: 负责语法分析以及代码生成。
作用域: 收集并维护由所有的标识符(及变量)组成的一系列查询,并实施一套严格的规则,确定当前执行的代码对这些变量的访问权限。

变量赋值执行的两个操作:

编译器在当前作用域中声明该变量(如果之前没有声明过)。
运行时引擎会在作用域中查找该变量,如果找到就对它进行赋值操作。

引擎查找变量的两个类型:

LHS: 变量出现在赋值操作的左侧执行LHS查询。(找到目标变量)
RHS: 变量出现在赋值操作的右侧执行RHS查询。(取到它的源值)

3. 作用域嵌套

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

4. 异常

如果RHS查询在所有的嵌套作用域中都找不到所需的变量,引擎就会抛出  ReferenceError异常。
如果LHS查询在所有的嵌套作用域中都找不到所需的变量,则会在全局作用域中创建一个具有该名称的变量,并将其返回给引擎。(程序在非严格模式下)。
如果RHS查询找到了一个变量,但是你对其进行不合理的操作,比如:对一个非函数类型的值进行函数调用;引用null或undefined类型中的属性,引擎会抛出  TypeError的异常。

二、词法作用域

作用域的工作模型:词法作用域和动态作用域(少数编程语言使用)。

1. 什么是词法作用域?

词法作用域是由你在写代码时将变量和块作用域写在哪里决定的。因此词法分析器在处理代码时会保持作用域不变。也就是我们在JavaScript中所说的作用域。

2. 作用域查找

作用域查找会在找到第一个匹配的标识符时停止。在多层的嵌套作用域中可以定义同名的标识符(遮蔽效应)。
注意:
无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数声明时所处的位置决定。
词法作用域只会查找一级标识符。

3. 欺骗词法

1. eval

eval(…)函数可以接受一个字符串作用参数,并将其中内容好像在书写代码时就存在于程序中的这个位置。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69986098/viewspace-2729329/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2020-10-24

  • 博文量
    10
  • 访问量
    3705