likes
comments
collection
share

图解javascript作用域

作者站长头像
站长
· 阅读数 45

本文原文地址

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

作用域访问规则

let count = 0;

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

func();

下面我们来看看变量count是如何被打印出来:

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

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

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

如下图所示:

图解javascript作用域

通过上面的示例代码,我们可以知道一个规则,作用域访问顺序:函数作用域 ——> 模块作用域 ——> 全局作用域

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

作用域创建规则

JavaScript中的作用域是词法作用域(相对于动态作用域)。

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

无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处的位置决定,这就是JavaScript的词法作用域。(除非你使用 with 或者 eval 欺骗它)

我们来看下面的例子:

let count = 0;

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

func('func');

代码执行,作用域创建顺序:

  1. 优先创建全局作用域,如全局window对象,或者挂载在全局的函数或属性;

  2. 之后模块作用域被创建,`count`变量会挂载在模块作用域,`func`函数也是挂载在模块作用域;

  3. 最后才是函数作用域,此时全局作用域和模块作用域已创建生成,如果它需要使用外部的存在的变量或方法,只需向上查找即可;

如下图所示:

图解javascript作用域

上图中作用域创建是至上而下,我省略了表示递进关系的线条。我们来归纳一下,**作用域创建顺序是:**全局作用域 ——> 模块作用域 ——> 函数作用域

总结

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

以上内容希望可以帮助到你,你的点赞、收藏是我更新的动力!!

参考

MDN文档

《你不知道的Javascript上卷》

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

更多

图解javascript的this指向

图解javascript原型链

javascript闭包使用

转载自:https://juejin.cn/post/7202036660636549178
评论
请登录