作用域
含义:作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性。换句话说,作用域决 定了代码区块中变量和其他资源的可见性。
也可以这样理解:作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6的到来,为我们提供了‘块级作用域’,可通过新增命令let和const来体现。
全局变量和局部变量
- 全局变量
在任何地方都可以访问到的变量就是全局变量,对应全局作用域 - 局部变量
只在固定的代码片段内可访问到的变量,最常见的例如函数内部。对应局部作用域(函数作用域)
无论是var还是let定义在{}外面都是全局变量
var num = 123;
let num = 123;
将var定义的变量放到一个单独的{}里面, 还是一个全局变量
{
var num = 123;
}
console.log(num); //不会报错
将let定义的变量放到一个单独的{}里面, 是一个局部变量
{
let num = 123;
}
console.log(num); //会报错
全局作用域有个弊端:如果我们写了很多行 JS 代码,变量定义都没有用函数包括,那么它们就全部都在全局作用域中。这样就会 污染全局命名空间, 容易引起命名冲突。
这就是为何 jQuery、Zepto 等库的源码,所有的代码都会放在(function(){…})()中。因为放在里面的所有变量,都不会被外泄和暴露,不会污染到外面,不会对其他的库或者 JS 脚本造成影响。这是函数作用域的一个体现。
块级作用域
含义:任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。
块级作用域在如下情况被创建:
- 在一个函数内部
- 在一个代码块(由一对花括号包裹)内部
块级作用域有以下几个特点:
- 声明变量不会提升到代码块顶部
- 禁止重复声明
- 循环中的绑定块作用域的妙用
在 js 中词法作用域规则:
- 函数允许访问函数外的数据.
- 整个代码结构中只有函数可以限定作用域.
- 作用域规则首先使用提升规则分析
- 如果当前作用规则中有名字了, 就不考虑外面的名字
var num = 123;
function foo() {
console.log( num );
}
foo();
if ( false ) {
var num = 123;
}
console.log( num ); // undefiend
作用域链
只有函数可以制造作用域结构, 那么只要是代码,就至少有一个作用域, 即全局作用域。凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。
将这样的所有的作用域列出来,可以有一个结构: 函数内指向函数外的链式结构。就称作作用域链。
function f1() {
var num = 123;
function f2() {
console.log( num ); }
f2();
}
var num = 456;
f1();
```![在这里插入图片描述](https://img-blog.csdnimg.cn/20191120170340112.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDAyMjM3NA==,size_16,color_FFFFFF,t_70)