块级作用域的了解

  • 时间:2021-03-20 02:20 作者:老衲不生气 来源: 阅读:679
  • 扫一扫,手机访问
摘要:引言因为JavaScript 存在变量提升这种特性,从而导致了很多与直觉不符的代码,这也是 JavaScript 的一个重要设计缺陷。作用域作用域是指在程序中定义变量的区域,该位置决定了变量的生命周期。浅显地了解,作用域就是变量与函数的可访问范围,即作用域控制着变量和函数的可见性和生命周期。在 ES

引言

因为JavaScript 存在变量提升这种特性,从而导致了很多与直觉不符的代码,这也是 JavaScript 的一个重要设计缺陷。

作用域

作用域是指在程序中定义变量的区域,该位置决定了变量的生命周期。浅显地了解,作用域就是变量与函数的可访问范围,即作用域控制着变量和函数的可见性和生命周期。

在 ES6 之前,ES 的作用域只有两种:全局作用域和函数作用域。

1、全局作用域  中的对象在代码中的任何地方都能访问,其生命周期伴随着页面的生命周期。

2、函数作用域  就是在函数内部定义的变量或者者函数,并且定义的变量或者者函数只能在函数内部被访问。函数执行结束之后,函数内部定义的变量会被销毁。

块级作用域就是使用一对大括号包裹的一段代码,比方函数、判断语句、循环语句,甚至单独的一个{}都可以被看作是一个块级作用域。

示例代码

简单来讲,假如一种语言支持块级作用域,那么其代码块内部定义的变量在代码块外部是访问不到的,并且等该代码块中的代码执行完成之后,代码块中定义的变量会被销毁。

变量提升所带来的问题

1. 变量容易在不被察觉的情况下被覆盖掉

2. 本应销毁的变量没有被销毁

为理解决这些问题,ES6 引入了 let 和 const 关键字,从而使 JavaScript 也能像其余语言一样拥有了块级作用域。

使用 let 关键字公告的变量是可以被改变的,而使用 const 公告的变量其值是不可以被改变的。但不论怎么,两者都可以生成块级作用域,

JavaScript 是如何支持块级作用域的

实例代码

如图,分析代码流程:

第一步是编译并创立执行上下文

刚开始的foo执行上下文

从图中可知:
1、函数内部通过 var 公告的变量,在编译阶段全都被存放到变量环境里面了。

2、通过 let 公告的变量,在编译阶段会被存放到词法环境(Lexical Environment)中。

3、在函数的作用域块内部,通过 let 公告的变量并没有被存放到词法环境中。

第二步继续执行代码,当执行到代码块里面时,变量环境中 a 的值已经被设置成了 1,词法环境中 b 的值已经被设置成了 2

执行 foo 函数内部作用域块时的执行上下文  

从图中可知:

当进入函数的作用域块时,作用域块中通过 let 公告的变量,会被存放在词法环境的一个单独的区域中,这个区域中的变量并不影响作用域块外面的变量,比方在作用域外面公告了变量 b,在该作用域块内部也公告了变量 b,当执行到作用域内部时,它们都是独立的存在。

再接下来,当执行到作用域块中的console.log(a)这行代码时,就需要在词法环境和变量环境中查找变量 a 的值了,具体查找方式是:沿着词法环境的栈顶向下查询,假如在词法环境中的某个块中查找到了,就直接返回给 JavaScript 引擎,假如没有查找到,那么继续在变量环境中查找。

执行到console.log(a)

当作用域块执行结束之后,其内部定义的变量就会从词法环境的栈顶弹出

最终执行上下文


块级作用域就是通过词法环境的栈结构来实现的,而变量提升是通过变量环境来实现,通过这两者的结合,JavaScript 引擎也就同时支持了变量提升和块级作用域了。

  • 全部评论(0)
手机二维码手机访问领取大礼包
返回顶部