几乎每一种编程语言,它最基本的能力都是能够存储变量当中的值、并且允许我们对这个变量的值进行访问和修改。那么有了变量之后,应该把它放在那里、程序如何找到它们?这是不是需要我们提前约定好一套存储变量、访问变量的规则?这套规则,就是我们常说的作用域。作用域本质上就是程序存储和访问变量的规则。更多时候,我们提到作用域的时候,指的是这个规则约束下的一个变量、函数、标识符可以被访问的区域(这时它就更具体了)。
ES5中的作用域
ES5只有全局作用域和函数作用域,其有两条比较重要的规则:
使用var声明的变量会被自动添加到最接近的环境中。
如果初始化时没有使用var声明,该变量会自动被添加到全局环境中。
例如:
function add(num1,num2){
var sum = num1+num2;
return sum;
}
var result = add(10,20);
alert(sum); //报错 由于sum不是有效的变量
由于使用var 所以sum被添加到add函数的局部环境中,alert(sum)是其父执行环境,故无法访问。
将sum前的var去掉就可以访问,这时sum被添加到全局环境中
全局作用域
声明在任何函数之外的顶层作用域的变量就是全局变量,这样的变量拥有全局作用域。
var char1="A";
function doSomething(){
var char2="B";
char3 = "C";
function innerSay(){
console.log(char2);
}
innerSay();
}
window.char4 = "D";
console.log(char1); // A 在最外层函数外面定义的变量拥有全局作用域
console.log(char2); // Uncaught ReferenceError: char2 is not defined
doSomething(); //B 最外层函数拥有全局作用域
doSomething();console.log(char3); // C,前提doSomething()需要先执行 所有末定义(没有var)直接赋值的变量自动声明为拥有全局作用域
innerSay() // Uncaught ReferenceError: innerSay is not defined
console.log(window.char4); // D 所有window对象的属性拥有全局作用域
局部作用域(函数作用域)
声明在函数内部的变量,局部作用域一般只在固定的代码片段内可访问到,最常见的是函数内部,因此也称函数作用域。
上述代码中变量char2仅拥有局部作用域,只能在函数doSomething内部访问到。
在严格模式下,函数只能在顶层作用域和函数内声明,其他情况(比如if代码块,循环代码块)下的声明都会报错.
ES6中的块作用域
块作用域是伴随ES6而生的一个概念。
ES6 开始,我们迎来了了两个用于声明变量的新关键词: let 和 const。这两个关键字定义的变量,如果被一个大括号 { } 这样括住了,那么这个大括号就是一个代码块,大括号括住的这些变量集就形成了一个块作用域。
let,const声明的变量只在所处于的块级有效;
const声明恒定变量,声明的同时就必须赋值,否则会报