let、const与var

下面所有代码皆可按 F12,进入Console运行

作用

相同之处:声明变量
不同之处:声明变量类型、变量提升、变量的暂时性死区、变量重复声明、作用域

声明类型

  1. let 与 var 都能够声明任意类型变量;
  2. const 只能声明只读常量。对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址,const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变。
const a = 2
a = 4 // TypeError: Assignment to constant variable.

// 声明复合类型变量
const b = [1, 2, 3]
console.log(b) // [1, 2, 3]
b[1] = 4
console.log(b) // [1, 4, 3]

变量提升

  1. 使用 var 声明变量,变量使用与声明顺序没有要求
function f_var() {
    console.log(a)
    var a = 10
}
f_var() //undefined  
  • 注:undefined 表示变量已经声明,但没有值 *
  1. 使用 let/const 声明变量,变量一定要在声明后使用
function f_let() {
    console.log(b)
    let b = 10
}
f_let() // ReferenceError: Cannot access 'b' before initialization

function f_const() {
    console.log(c)
    const c = 10
}
f_const() // ReferenceError: Cannot access 'c' before initialization

暂时性死区

含义:如果只使用 var 声明的变量,由于 var 声明的变量存在变量提升,所以只要在区域内声明了变量,无论在任何位置都可以使用。如果在代码块内存在 let/const 命令声明的变量,那么所声明的变量就“绑定”(binding)这个区域,所以使用 let/const 命令声明变量之前,该变量都是不可用的。

function f_var() {
    console.log(a)
    if (true) {
         console.log(a)
    }
    if (true) {
        var a = 1
    }
}
f_var() // undefined   undefined   

function f_let() {
    var a = 1
    if (true) {
        console.log(a)
        let a = 3
    }
}
f_let() // ReferenceError: Cannot access 'a' before initialization

function f_const() {
    var a = 1
    if (true) {
        console.log(a)
        const a = 3
    }
}
f_const() // ReferenceError: Cannot access 'a' before initialization
  • 例子 f_var() 中,只有 var 声明变量,所以在只要声明了变量,在 f_var() 任何一个位置都可以使用。
  • 例子 f_let 和 f_const 中,虽然在 if 区域外部使用了 var 声明了变量,但是由于 if 内部使用了 let/const 声明了同一个变量,所以变量会绑定该区域,所以在声明之前该变量都无法使用。

不允许重复声明

  • 使用 var 声明变量,可多次声明同一名称变量
  • 使用 let/const 声明变量,在同一作用域内,只能声明一次。
 // SyntaxError: Identifier 'a' has already been declared
function f_let() {
    var a = 1
    let a = 1    
} 

 // SyntaxError: Identifier 'a' has already been declared
function f_let() {
    let a = 1
    let a = 1    
} 
// SyntaxError: Identifier 'a' has already been declared
function f_let(a) {
    let a = 2
}

// 不报错,具体原因情况变量作用域相关内容
function f_let(a) {
    {
        let a = 2
    }
}

作用域

  • ES5 只有全局作用域和函数作用域,所以使用 var 声明变量时,容易出现下面不合理的场景
// 场景一,内层变量覆盖外层变量
var tmp = 'outside'
function f() {
    console.log(tmp)
    if (false) {
        var tmp = "inside"
    }
}
f() // undefined; 由于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。

// 场景二: 用来计数的循环变量泄露为全局变量
var s = 'outside'
for (var i = 0; i < s.length; i++) {
    console.log(s[i])
}
console.log(i) // 5; 变量 i 在循环结束后,泄露成了全局变量。
  • ES6中的 let/const 为 JavaScript 新增加块级作用域
function f1() {
    let n = 5
    if (true) {
        let n = 10
    }
    console.log(n) // 5; 内层 if 的作用域变量不影响外部变量
}

{
    {let insane = 'Hello World'}
    console.log(insane) // 报错, 变量在内部声明,无法在外部使用
};

{
    let insane = 'Hello World'
    {let insane = 'Hello World'} // 不报错,内层作用域可以定义外层作用域的同名变量。
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • let 概念: 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。 1、不存在变量提升 var命令会发生...
    简单背包客阅读 11,843评论 0 7
  • let 命令 块级作用域 const 命令 顶层对象的属性 global 对象 let 命令 基本用法 ES6 新...
    嘉奇呦_nice阅读 5,526评论 0 2
  • 本文属个人笔记,不做详解,仅供参考! let命令 基本用法 ES6 新增了let命令,用来声明变量。它的用法类似于...
    R_yan阅读 29,193评论 6 18
  • let 和 const 命令 let 命令 块级作用域 const 命令 顶层对象的属性 gl...
    安小明阅读 4,522评论 0 0
  • let 命令 块级作用域 const 命令 顶层对象的属性 global 对象 let 命令 基本用法 ES6 新...
    卞卞村长L阅读 3,725评论 0 0