作用域
ES5中的作用域有:全局作用域、函数作用域,ES6中新增了块级作用域。块作用域由 { } 包括,if
语句和 for
语句里面的 { } 也属于块作用域。
var
1.没有块级作用域的概念,但具有函数全局作用域、函数作用域的概念
{
var a = 10
}
console.log("输出", a) //输出10
var a = 10
function test() {
console.log("输出", 10) //输出 10
var a = 10
}
console.log(a) //a is not defined
2.存在变量提升
变量提升(hoisting)是JavaScript中的一种行为,它使得变量和函数声明在代码执行前被提升至当前作用域的顶部。然而,变量的初始化并不会被提升
console.log(x); // 输出: undefined
var x = 5;
3.全局作用域用 var
声明的变量会挂载到 window
对象下,let 和const不会,node环境中都不会挂载到global对象
4.同一作用域中允许重复声明,以最后一次声明为准
var a = 10;
var a = 20;
console.log(a); //20
checkscope();
function checkscope(){
var b = 10;
var b = 20;
console.log(b); //20
}
let
1.有块级作用域的概念
{
let a = 10;
}
console.log(a); //ReferenceError: a is not defined
2.不存在变量提升且具有暂时性死区
console.log(a); //ReferenceError: Cannot access 'a' before initialization
let a = 10;
暂时性死区(Temporal Dead Zone,简称 TDZ)是ES6(ECMAScript 2015)引入的新概念,主要与let和const声明有关。在TDZ中,变量在声明之前是不可访问的,这有助于避免某些常见的编程陷阱和错误。
TDZ 的工作原理:
在使用let或const声明变量的作用域中,从作用域的开始直到变量声明语句之前,变量处于暂时性死区。在TDZ中试图访问变量会导致ReferenceError,因为此时变量尚未正式声明。
TDZ 的工作原理
在使用let或const声明变量的作用域中,从作用域的开始直到变量声明语句之前,变量处于暂时性死区。在TDZ中试图访问变量会导致ReferenceError,因为此时变量尚未正式声明。
3.同一块作用域中不允许重复声明
{
let A;
var A; //SyntaxError: Identifier 'A' has already been declared
}
{
var A;
let A; //SyntaxError: Identifier 'A' has already been declared
}
{
let A;
let A; //SyntaxError: Identifier 'A' has already been declared
}
const
1.必须立即初始化,不能留到以后赋值
const a; // SyntaxError: Missing initializer in const declaration }
2.常量的值不能改变
{
const a = 10;
a = 20; // TypeError: Assignment to constant variable
}
但是,对于使用const声明的数组或对象,其内部的属性是可以改变的
const a = [10, 20]
a[1] = 2
console.log(a)
const b = {
'name': '张三'
}
b.name = '李四'
console.log(b)
/*
输出
[ 10, 2 ]
{ name: '李四' }
*/
3.不存在变量提升且具有暂时性死区
console.log(y); // 输出: ReferenceError: y is not defined
const y = 10;
面试真题
- let const var 的区别?什么是块级作用域?如何用?
参考答案:
- var 定义的变量,没有块级作用域的概念,具有变量提升,可重复声明。
- let 定义的变量,只能在块作用域里访问,无变量提升,不可以重复声明,具有暂时性死区。
- const 用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改,无变量提升,不可以重复声明,具有暂时性死区。
最初在 JS 中作用域有:全局作用域、函数作用域。没有块作用域的概念。
ES6 中新增了块级作用域。块作用域由 { } 包括,if 语句和 for 语句里面的 { } 也属于块作用域。
在以前没有块作用域的时候,在 if 或者 for 循环中声明的变量会泄露成全局变量,其次就是 { } 中的内层变量可能会覆盖外层变量。块级作用域的出现解决了这些问题。
总结
主要就是4个方面
1.是否有块级作用域
2.是否变量提示生
3.是否有暂时性死区
4.是否可重复声明
后续增加
- JavaScript为什么要进行变量提升,它导致了什么问题
- let var 在闭包中应用