乐趣区

关于前端:图解javascript作用域

图解 javascript 作用域

本文原文地址

此文章是答复知乎问题总结而来。

作用域拜访规定

let count = 0;

function func() {console.log(count);
}

func();

上面咱们来看看变量 count 是如何被打印进去:

1. `func` 函数调用,`console.log` 打印 `count` 变量,查找以后函数作用域,是否存在变量 `count`;2. 不存在持续向上查找,查找模块作用域,发现 `count` 变量存在,并且打印出变量的值。

如果模块作用域仍然不存在 count 变量?

会持续向上查找,查找全局作用域是否存在 count 变量,如果仍然不存在,提醒undefined

如下图所示:

通过下面的示例代码,咱们能够晓得一个规定,作用域拜访程序:函数作用域 ——> 模块作用域 ——> 全局作用域

提醒:作用域拜访的方向是不可逆 只有由里向外拜访,先函数,再模块,最初全局;

作用域创立规定

JavaScript 中的作用域是词法作用域(绝对于动静作用域)。

什么叫词法作用域?顾名思义,词法作用域就是定义在词法阶段的作用域。换句话说,词法作用域是由你在写代码时将变量和块作用域写在哪来决定的。

无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被申明时所处的地位决定,这就是 JavaScript 的词法作用域。(除非你应用 with 或者 eval 坑骗它)
咱们来看上面的例子:

let count = 0;

function func(name) {console.log(count, name);
}

func('func');

代码执行,作用域创立程序:

1. 优先创立全局作用域,如全局 window 对象,或者挂载在全局的函数或属性;2. 之后模块作用域被创立,`count` 变量会挂载在模块作用域,`func` 函数也是挂载在模块作用域;3. 最初才是函数作用域,此时全局作用域和模块作用域已创立生成,如果它须要应用内部的存在的变量或办法,只需向上查找即可;

如下图所示:

上图中作用域创立是至上而下,我省略了示意递进关系的线条。咱们来演绎一下,作用域创立程序是:全局作用域 ——> 模块作用域 ——> 函数作用域

在调用实现之后,作用域也会相应开释。如果是存在闭包,作用域链就会被保留,能够看看:闭包装逼失败(闭包应用) – 掘金。

总结

  • 作用域拜访程序:函数作用域 ——> 模块作用域 ——> 全局作用域
  • 作用域拜访的方向是不可逆 只有由里向外拜访
  • 作用域创立程序是:全局作用域 ——> 模块作用域 ——> 函数作用域

以上内容心愿能够帮忙到你,你的点赞、珍藏是我更新的能源!!

参考

MDN 文档

《你不晓得的 Javascript 上卷》

冴羽 · JavaScript 深刻之执行上下文

退出移动版