一、作用域
JS中,作用域为function内的区域,称为函数作用域。
二、变量声明
在ES6之前,通过var声明一个变量,但是ES6之后,又添了两个关键词来声明变量:let和const
var:声明了一个变量,这个变量的作用域是当前执行的上下文
let:声明了一个块级域的局部变量,并且它声明的变量只在所在的代码块内有效
const:声明了一个只读的块级域的常量,并且它声明的变量只在所在的代码块内有效
1 { // 代码块 2 var a = 1; 3 let b = 2; 4 const c = 3; 5 6 console.log(a); // 1 7 console.log(b); // 2 8 console.log(c); // 3 9 } 10 11 console.log(a); // 1 12 console.log(b); // 报错,ReferenceError: b is not defined(…) 13 console.log(c); // 未执行, 因为上面语句出错,所以这条语句不再执行,如果上面的语句不报错,那么这里就会报错
1 (function (){ 2 var a = 1; 3 let b = 2; 4 const c = 3; 5 6 console.log(a); // 1 7 console.log(b); // 2 8 console.log(c); // 3 9 })(); // 为了方便,这里使用了自执行函数 10 11 console.log(a); // 报错,ReferenceError: a is not defined(…) 12 console.log(b); // 未执行 13 console.log(c); // 未执行
let和const不像var那样,会发生变量提升现象
1 console.log(a); // 报错,ReferenceError: a is not defined 2 let a = 2; 3 console.log(a); // 待执行
ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
三、变量声明提升
JS在执行前会对整个脚本文件的声明部分做完整解析(包括局部变量),从而确定变量的作用域。
当局部变量与全局变量重名时,局部变量的范围会覆盖全局变量的范围。当离开局部变量的范围后,又回到全局变量的范围。
1 var a=1; 2 function test(){ 3 alert(a); //undefined 此处a并不是全局变量,函数里面已经声明了一个重名的局部变量,所以全局变量会被覆盖,JS执行前会对声明部分解析,所以此处的a只是声明但未赋值 4 a=4; //此处a被赋值 5 alert(a); //4 ,此处a仍是局部变量 6 var a; //局部变量a在这里声明 7 alert(a); //4 8 } 9 test(); 10 alert(a); //1,此处a为全局变量
1 var a=10; 2 function test(){ 3 a=100; 4 alert(a); //100 此处a为局部变量,如果没有第三行a=100,此处则为undefined,有了第三行,此处局部变量被赋值为100 5 alert(this.a); //10 函数内部的this指向的是函数调用者,在这里函数是被全局对象调用,所以此处的this指向全局对象(这里指window) 6 var a; 7 alert(a); //100 /局部变量100 8 } 9 test()
在基本的语句(或者说代码块)中(比如:if语句
、for语句
、while语句
、switch语句
、for...in语句
等),不存在变量声明提升
四、函数声明提升
函数声明和函数表达式在语法上是等价的,但有一点不同,函数声明会被提到作用域顶部,而函数表达式不会。
1 fun(); // hello 2 3 function fun(){ 4 console.log("hello"); 5 } 6 7 // -------------- 8 // 提升后 9 10 function fun(){ 11 console.log("hello"); 12 } 13 14 fun(); // hello
1 fun(); // 报错,TypeError: fun is not a function 2 3 var fun = function(){ 4 console.log("hello"); 5 }; 6 7 // -------------- 8 // 提升后 9 10 var fun; 11 12 fun(); // 报错,TypeError: fun is not a function 13 14 fun = function(){ 15 console.log("hello"); 16 };