作用域
作用域,顾名思义,就是变量能起作用的区域。我们在写在程序的时候会声明很多的变量,不同方式生成的变量其可被调用或存在的区域也不同。作用域明确了变量的访问权限。
作用域负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。
ps:广义的作用域有两种模型。词法作用域和动态作用域。而在js的规则中采用的是词法作用域模型。
js中的三种作用域
1.全局作用域
-
产生:全局作用域在浏览器或者程序刚开始运行时产生
function foo(){ var a = 2; funtion baz(){ b = 3;//b的作用域也是全局的 } } var c = 4;//c的作用域就是全局的,因为它声明在函数的外部
2.函数作用域/局部作用域
-
产生:函数作用域在函数声明时产生
-
定义:属于这个函数的全部变量都可以在整个函数范围内使用及复用,嵌套的作用域中也可以使用。
function foo(){ var a = 2; console.log(b);//undefined function baz(){ var b = 3; console.log(a);//在baz里可以访问a } }函数作用域是针对于函数的,它是一种局部的作用域。假设我们声明一个函数foo( )之后,这个函数产生一个小气泡(就是花括号里的部分),这个气泡就是它的作用域,这其中包含了标识符a,baz。由于函数作用域的存在,我们在这个气泡之外无法访问a和baz,但在气泡之内却可以。
3.块级作用域
- 定义:块级作用域指的是,变量和函数属于某个代码块中。
不同于函数作用域属于一个函数内,块级作用域可以实现一个更小范围的封装。
在ES6中引入了let和const两种比较典型的方式来实现块级作用域。(其他的还有with和try/catch)
{
let a = 0;
}
{
var b = 1;
}//这里的花括号有跟没有一样
console.log(a); //undefinded
console.log(b); //1
在这个例子中let所声明的i仅仅附属于{let ...}这个代码块中,所以在花括号的外部我们无法访问它。
利用这个特性我们经常可以在for循环里见到它
var sum=0;
for(let i=0;i<10;i++){
sum=sum+i;
}
console.log(sum); //45
console.log(i); //i is not defind
在循环中,i通常是充当一个计数器的作用,在循环的外部我们很少用到它。用let去声明i,既可以实现循环,也能保证不污染到其他的作用域。这就是块级作用域的作用。