全局作用域
全局作用域:
就是代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性,更重要的是减少命名冲突。比如整个script标签或者一个单独的js文件。
局部作用域(函数作用域):
在函数内部就是局部作用域,这个代码的名字只在函数内部起效果和作用
块级作用域(ES6新增作用域):
- 使用ES6中新增的let和const指令可以声明块级作用域,块级作用域可以在函数中创建也可以在一个代码块中创建(由 '{ }'包裹的代码片段)
- let和const声明的变量不会有变量提升,也不可以重复声明
- 在循环中比较适合绑定块级作用域,这样就可以把声明的计数器变量限制在循环内部。
变量也分为两种,全局变量和局部变量:
全局变量:
在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。
- 全局变量在代码的任何位置都可以使用
- 在全局作用域下var声明的变量是全局变量
- 在函数内部不使用var声明直接定义的变量也是全局变量(不建议使用)。
局部变量:
在局部作用域下声明的变量叫局部变量(在函数内定义的变量)
- 局部变量只能在该函数内部使用
- 在函数内部var声明的变量是局部变量
- 函数的形参实际上就是局部变量
全局变量和局部变量的区别
- 全局变量:在任何一个地方都可以使用,只有浏览器关闭时才会被销毁,因此比较占用内存
- 局部变量:在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间。
作用域链:
内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构我们称为作用域链,采用就近原则。
例1:下面的代码输出结果为?
function f1() {
var num = 123;
function f2() {
console.log(num);
}
f2();
}
var num = 456;
f1();
解:可以画图分析,如下图所示,0级链为f1和全局变量num=456;1级链为num=123和f2;2级链为console.log(num);然后根据就近原则,可得输出结果为123.
例2:下面代码输出结果为?
再次根据链式查找和就近原则,可以得出a=4;b='22';
以上是我自己编写的内容,参照了b站pink老师的视频。后来参考了他人的文章,决定转载一篇来补充( 转载于:作者:CUGGZ\链接:[juejin.cn/post/694094…
2. 对作用域、作用域链的理解
1)全局作用域和函数作用域
(1)全局作用域
- 最外层函数和最外层函数外面定义的变量拥有全局作用域
- 所有未定义直接赋值的变量自动声明为全局作用域
- 所有window对象的属性拥有全局作用域
- 全局作用域有很大的弊端,过多的全局作用域变量会污染全局命名空间,容易引起命名冲突。
(2)函数作用域
- 函数作用域声明在函数内部的变零,一般只有固定的代码片段可以访问到
- 作用域是分层的,内层作用域可以访问外层作用域,反之不行
2)块级作用域
- 使用ES6中新增的let和const指令可以声明块级作用域,块级作用域可以在函数中创建也可以在一个代码块中的创建(由
{ }包裹的代码片段) - let和const声明的变量不会有变量提升,也不可以重复声明
- 在循环中比较适合绑定块级作用域,这样就可以把声明的计数器变量限制在循环内部。
作用域链: 在当前作用域中查找所需变量,但是该作用域没有这个变量,那这个变量就是自由变量。如果在自己作用域找不到该变量就去父级作用域查找,依次向上级作用域查找,直到访问到window对象就被终止,这一层层的关系就是作用域链。
作用域链的作用是保证对执行环境有权访问的所有变量和函数的有序访问,通过作用域链,可以访问到外层环境的变量和函数。
作用域链的本质上是一个指向变量对象的指针列表。变量对象是一个包含了执行环境中所有变量和函数的对象。作用域链的前端始终都是当前执行上下文的变量对象。全局执行上下文的变量对象(也就是全局对象)始终是作用域链的最后一个对象。
当查找一个变量时,如果当前执行环境中没有找到,可以沿着作用域链向后查找。
作者:CUGGZ
链接:juejin.cn/post/694094…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。