大家好,关于作用域及作用域链,是前端开发中JavaScript部分高级的内容,一般在JS初学者很难遇到相关的应用,但是要基于JS封装更优秀更高级的代码,就必须对JS的作用域进行透彻的理解,才能写出高质量的代码,这也是前端开发程序员面试中经常会聊到的一个话题。如果您是前端大牛,如果有自己的理解欢迎在评论区留言或相互关注,进行深层次的研究和探讨。
1. 作用域
1.1. 基本概念
在js中,执行环境(execution context)是一个非常重要的概念。
程序代码运行时,会产生一个专门用来管理所需的变量和函数的对象---环境对象,这个对象我们不能通过代码编写操作他,但解析器在处理数据时会在后台使用他。
全局环境就是最外围的一个执行环境,可以在代码任意位置访问到。在浏览器中,全局环境就是window对象(因此,所有的全局变量和函数,都是window对象上的属性和方法)。

上面代码,定义了name变量和doSomething函数,都属于全局函数,所以任意位置都可以访问。
而anotherName 和showName则叫做局部变量,不能被外部访问。
JavaScript没有块作用域:

局部环境以函数为主。每个函数都有自己独立的执行环境。
局部作用域一般只在固定的代码片段内可访问到,最常见的就是函数内部,所以在很多地方就会有人把它称为函数作用域。

同样的代码,anotherName变量和showName函数定义在doSomething函数内部,外部不可见。在小范围可以访问的变量,这就是局部变量。
没有块作用域
var foo = true;
if (foo) {
var bar = foo * 2;
console.log( bar );
}
console.log( bar );
这样变量范围就缩小了。回到之前问题:
for (var i=0; i<10; i++) {
console.log( i );
}
console.log( i );
为什么全局就可以在局部中访问呢?接下来,就要看看作用域链。
1.2. 作用域链
在生活中,我们每个人都有很多圈子:

代码在一个作用域中执行,会创建相关资源(变量 和 函数)的一个作用域链。他的用途是来保存当前执行代码所需要的所有变量和函数。默认遵循“从里到外”的查找规则。
定义
如下图:

气泡1包含着整个全局作用域,其中只有一个标识符:foo。
气泡2包含着foo所创建的作用域,其中有三个标识符:a、bar和b。
气泡3包含着bar所创建的作用域,其中只有一个标识符:c。
作用域气泡由其对应的作用域块代码写在哪里决定,它们是逐级包含的。
查找
作用域气泡的结构和互相之间的位置关系给引擎提供了足够的位置信息,引擎用这些信息来查找标识符的位置。无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处的位置决定,共享给子集。
气泡示例图,如下:

关于函数中的作用域和块作用域的相关知识,我们下次再详细讲解,有兴趣的朋友,欢迎关注。如果您是前端大牛,也欢迎在评论区发表您的见解,谢谢!不论您是小白还是大牛,愿意交个朋友,欢迎关注。