一.作用域
作用域指变量所作用的范围,在 Javascript 中有两种作用域:
1.全局作用域
2.函数作用域
二.变量的提升
变量提升:具体表现就是所有通过 var 声明的变量会提升到当前作用域的最前面。
function bar() {
console.log(temp);
var temp;
}
bar(); // undefined
可以看到用 var 声明了的并不会报错。因为其实函数 bar 等同于
function bar() {
var temp;
console.log(temp);
}
三.块级作用域
理解:
在一个代码块(括在一对花括号中的一组语句)中定义的所有变量在代码块的
外部是不可见的。定义在代码块中的变量在代码块被执行结束后会变释放掉。
ES6 中规定了 let 和 const 来支持块级作用域。
四.let
使用方法基本和 var 相同,而且声明的变量只在其块和子块中可用,这点也与 var 相同。 二者之间最主要的区别在于 var 声明的变量的作用域是整个封闭函数。
function foo() {
if(true) {
var temp = 5;
console.log(temp);
}
console.log(temp);
}
function bar() {
if(true) {
let temp = 5;
console.log(temp);
}
console.log(temp);
}
foo(); // 5 和 5
bar(); // 5 和 "ReferenceError: temp is not defined
let 声明的变量的作用域只是外层块,而不是整个外层函数。
五.const
const 跟 let 的语义相似,就是用来声明常量的,一旦声明了就不能更改。值得注意的是 const 声明的变量记录的是指针,不可更改的是指针,如果 const 所声明的是对象,对象的内容还是可以修改的。
// 重新赋值声明导致报错
const PI = 3.14;
PI = 3.1415926; // TypeError: Assignment to constant variable.
// 给对象增加属性不会导致 obj 的指针变化,所以不会报错
const obj = { foo: 2 };
obj.bar = 3;
console.log(obj); // {foo: 2, bar: 3}
六.暂时性死区
使用 let 或 const 声明的变量,在声明没有到达之前,访问该变量都会导致报错,就连一直以为安全的 typeof 也不再安全。
// TDZ1
function foo() {
// TDZ 开始
console.log(typeof temp);
let temp = 5; // TDZ 结束
}
foo(); // ReferenceError: temp is not defined
报的错是 ReferenceError,如果使用 var 声明的话,temp 输出应该是 undefined,从 let 声明的变量的块的第一行,到声明变量之间的这个区域被称作暂时性死区(TDZ)。凡是在这个区域使用这些变量都会报错。
// TDZ2
function bar() {
console.log(typeof temp);
}
bar(); // undefined
当 JS 引擎检视下面的代码块有变量声明时,对于 var 声明的变量,会将声明提升到函数或全局作用域的顶部,而对 let 或 const 的时候会将声明放在暂时性死区内。任何在暂时性死区内访问变量的企图都会导致“运行时”错误(runtime error)。只有执行到变量的声明语句时,该变量才会从暂时性死区内被移除并可以安全使用。
参考自链接:juejin.cn/post/684490…