js基础1 - 作用域解析

 在编程语言中,作用域是一套设计良好的规则,用于存储变量,访问或修改变量。

1 js引擎的执行过程解析

编译过程:

分词/语法分析(是指调用有状态的解析规则)  → 解析/词法分析(生成AST树) → 代码生成

js引擎执行过程

注:LHS查询  赋值

       RHS查询   取值

2 作用域

    js采用的作用域模型是词法作用域,即定义在词法阶段的作用域,表现上来看就是无论在哪调用,如何调用,作用域由声明的位置决定。想要运行时变更作用域,需要使用到欺骗词法,但是需要注意的是,使用欺骗语法的性能损耗比较大→引擎无法在编译阶段进行性能优化,也会被严格模式所影响。

    js中使用欺骗词法的方式:

 (1)  eval(...) 执行动态创建的代码(setTimeout(str,...),setInterval(str,...),new Function(args,str)...)

 (2) with(obj){ key = value} 将一个对象当作一个词法作用域,属性当作标识符处理

    js中的函数作用域:属于这个函数的全部变量都可以在整个函数的范围以及在嵌套的作用域中使用及复用。遵循最小暴露原则,规避冲突

因此在js变量查找的过程中,会存在遮蔽效应,即变量查找会在找到第一个匹配的标识符时停止(唯一可以访问到被遮蔽的变量就是全局变量,可通过window.a方式拿到-浏览器环境下)

 块作用域:一般情况下是指由{...} 包含的代码块形成的作用域,遵循最小授权原则。在js中存在的形式一般有

  (1) try...catch 语句中catch分句

 (2) 由let constd定义的变量的作用域

3 变量提升

 在js引擎执行过程中,在编译阶段会先提出变量声明,在作用域创建变量,在代码执行阶段进行变量赋值操作。即在同一作用域声明的函数以及变量的声明都会移动到其作用域的顶端。需要注意的是:

(1) 函数会先被提升,然后再是变量

(2) 函数声明会在声明的阶段就赋值,函数表达式的赋值是在运行阶段。

4 相关补充

(1)ReferenceError 作用域判别失败  TypeError 操作非法

(2)函数声明与函数表达式的最简单区分为  function在第一位的是函数声明,其余的为函数表达式 

(3)var a = function b(){ }   →  var a = function(){ b = self }

 (3)let循环的重新绑定行为

(4)词法作用域链 与 调用栈

词法作用域 作用域链 → 基于代码中作用域嵌套,变量定义的过程发生在代码的书写阶段(在写代码的阶段确定)

动态作用域 作用域链 → 基于调用栈(在运行时确定)

你可能感兴趣的:(js基础1 - 作用域解析)