引自
1. 变量的作用域(var与let的区别)
在函数之外声明的变量,叫做全局变量,因为它可被当前文档中的任何其他代码所访问。在函数内部声明的变量,叫做局部变量,因为它只能在当前函数的内部访问。
ECMAScript 6 之前的 JavaScript 没有语句块作用域;相反,语句块中声明的变量将成为语句块所在函数(或全局作用域)的局部变量。例如,如下的代码将在控制台输出 5,因为 x
的作用域是声明了 x
的那个函数(或全局范围),而不是 if
语句块。
if (true) { var x = 5; } console.log(x); // 5
如果使用 ECMAScript 6 中的 let
声明,上述行为将发生变化。
if (true) { let y = 5; } console.log(y); // ReferenceError: y 没有被声明
2. 变量的提升
含义为: 先使用变量稍后再声明变量而不会引发异常, 但是提升后的变量将返回undefined值
变量提升即相当于:
var x;
console.log(x); // undefinded
示例:
/** * 例子1 */ console.log(x === undefined); // true var x = 3; /** * 例子2 */ // will return a value of undefined var myvar = "my value"; (function() { console.log(myvar); // undefined var myvar = "local value"; })();
上面的例子也可以写成(相当于将var x; console.log(x))
/**
* 例子1
*/
var x;
console.log(x === undefined); // true x = 3; /** * 例子2 */ var myvar = "my value"; (function() { var myvar; console.log(myvar); // undefined myvar = "local value"; })();
由于存在变量提升,一个函数中所有的var
语句应尽可能地放在接近函数顶部的地方。这个习惯将大大提升代码的清晰度。
但是let变量为块级作用域,则不会存在变量提升
在 ECMAScript 6 中,let(const)将不会提升变量到代码块的顶部。因此,在变量声明之前引用这个变量,将抛出引用错误(ReferenceError)。这个变量将从代码块一开始的时候就处在一个“暂时性死区”,直到这个变量被声明为止。
console.log(x); // ReferenceError let x = 3;