# 经典整体

  • let、const、var 的区别?什么是块级作用域?如何使用?

答案如下。

# 声明变量关键字

在 JavaScript 中有 3 中声明变量的方式:

  1. var
  2. let
  3. const
    最初声明变量的关键字就是 var ,但是为了解决作用域问题,所以新增了 letconst 的声明方式。

# 什么是作用域

ES5 中的作用域有:全局作用域、函数作用域。
ES6 中新增了块级作用域,块级作用域有 {} 包括, if语句for语句 里面的 {} 也属于块级作用域。
更多内容在 《作用域和作用域链》文章中。

# var 关键字

  1. 没有块级作用域的概念
{
    var a = 1;
}
console.log(a); // 1
  1. 有全局作用域、函数作用域的概念
var a = 1; //a 具有全局作用域
function checkscope(){
    var b = 2; //b 具有函数作用域
    console.log(a); // 1
    console.log(b); // 2
}
checkscope();
console.log(b); // ReferenceError: b is not defind
  1. 不初始化的值默认是 undefined
var a;
console.log(a); // undefined
  1. 存在变量提升
    变量提升 就是将变量的声明部分提升到当前作用域的最顶端。
console.log(a); // undefined
var a = 1; // 全局作用域
checkscope();
function checkscope() {
    // 这里是函数作用域
    console.log(a); //undefined, 根据 this 情况,所以,此处的 a 为函数作用域中声明的 a,而不是全局作用的 a。
    var a; // 进行了状态提升。
}
  1. 全局作用用 var 声明的变量将会挂载到 window 对象下
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1
  1. 统一作用域中允许重复声明
var a = 1;
var a = 2;
console.log(a); // 2
checkscope();
function checkscope(){
    var b = 1;
    var b = 2;
    console.log(b); // 2
}

# let 关键字

  1. 具有块级作用的概念
{
    let a = 1;
}
console.log(a); // ReferenceError: a is not undefined
  1. 不存在变量提升
console.log(a); // ReferenceError: Cannot access 'a' before initialization, 不能在声明之前使用变量 a 。
let a = 1;
  1. 暂时性死区
{
    console.log(a); // ReferenceError: Cannot access 'a' before initialization, 不能在声明之前使用变量 a 。
    let a = 1;
}
if (true){
    // TDZ 开始
    console.log(a); // ReferenceError: Cannot access 'a' before initialization, 不能在声明之前使用变量 a 。
    
    let a; // TDZ 结束
    console.log(a); // undefined
    
    a = 2;
    console.log(a); // 2
}

在声明变量 a 之前的区域被称为暂时性死区(TDZ)。这个区域是指从当前作用域开始,到变量实际声明的位置之间的部分

  • 什么是暂时性锁区

ES6 规定, let、const 命令会使区块形成封闭作用域。若在声明之前使用变量,就会报错。
总之,在代码块内,使用 let、const 命令声明变量之前,该变量都是不可用的。
这种情况在语法上被成为” 暂时性死区 “,简称: TDZ
暂时性锁区的原因是没有变量提升

  1. 不初始化的值默认是 undefined
let a;
console.log(a); // undefined
  1. 同一块级作用域中不允许重复声明
{
    let a;
    var a; // Identifier 'a' has already been declared
}
{
    var a;
    let a; // Identifier 'a' has already been declared
}
{
    let a;
    let a; // Identifier 'a' has already been declared
}

# const 关键字

  1. 必须立即初始化,初始化后不能赋值
const a; // Missing initializer in const declaration
  1. 常量的值不能改变
const a = 1;
a = 2; // Assignment to constant variable

const 并不是变量的值不得改动,而是变量指向的内存地址所保存的数据不得改动。

# 总结

  • var 关键字
  1. 没有块级作用域概念
  2. 有全局作用域,函数作用域的概念
  3. 不初始化时,默认值为:undefined
  4. 存在变量提升
  5. 全局作用域 var 声明的变量挂载到 window 对象下
  6. 同一作用域中允许重复声明
  • let 关键字
  1. 有块级作用域的概念
  2. 不存在变量提升
  3. 暂时性锁区
  4. 不会像 var 成为全局对象的属性。
  5. 同一块级作用域中不允许重复声明
  • const 关键字
  1. 与 let 特性一样,但是有两个差别
  2. 差别 1:必须立即初始化,不能留到以后赋值
  3. 差别 2:常量的值不能改变

过去无法挽回,未来可以改变,有的人成日殚精竭虑,却掀不起什么风浪,有的人却因一念之差,让世界天翻地覆,这就是命运权重。

阅读次数

请我喝[茶]~( ̄▽ ̄)~*

NIDLH 微信支付

微信支付

NIDLH 支付宝

支付宝