作用域和自由变量
1. 作用域
作用域就是限制变量在代码中可以被访问的范围。
作用域分为全局作用域、函数作用域和块级作用域(ES6新增)。
1. 全局作用域:
全局作用域是最外层的作用域,比如script标签下的第一层:下面这个红框圈起来的就是全局作用域,a就是声明在全局作用域里的变量,可以在整个全局作用域内访问。
或者是整个js文件:整个js文件就是一个全局作用域。
2. 函数作用域
函数作用域指的是函数内部的作用域,声明在函数作用域内部的变量只能在函数作用域内访问,比如下面代码:声明在test函数内部的变量a,在外面是访问不到的。
function test() {
let a = 2;
}
console.log(a); // 访问不到
3. 块级作用域
因为ES6中let关键字的出现,块级作用域也随之产生,{}所包含的区域就是块级作用域。
{
let a = 1;
}
console.log(a); // 访问不到
类似于if(){}的都算是块级作用域。
是不是跟函数作用域有点类似,但是函数作用域是里面的变量声明无论是let声明还是var声明,外界都无法访问,而块级作用域里只有let声明的变量,外界才无法访问,var声明的变量外界是可以访问的。
{
var a = 1;
}
console.log(a); // 1
4. 作用域链
下文代码中有两个函数作用域:
let a0 = 0;
function fn1() {
let a1 = 1;
function fn2() {
let a2 = 2;
console.log(a1); // 1
}
fn2();
}
fn1();
可以看到在fn2函数中打印a1变量,是能够成功访问的,但是fn2的函数作用域并没有a1这个变量,但是fn2的父级作用域里有,fn2里访问不到变量a1,就会往父级作用域去找,如果父级作用域也没有就再往上一层找,这就是作用域链。
2. 自由变量
在当前作用域里面有使用但是没有声明的就叫做自由变量,像前文介绍作用域链时举例的变量a1就是自由变量。