let、const、var的区别与联系

156 阅读2分钟

一、作用域问题

var是函数作用域,一旦声明,在全局范围内都有效。

let是块级作用域,代码块内声明的变量在代码块之外调用会报错

{    let a = 10;    var b = 1;}console.log(a); //报错console.log(b) //1

for循环的计数器,适合使用let命令;且for循环有一个特殊之处,即设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc

二、是否存在变量提升

var存在“变量提升”,变量可以在声明之前使用,值为undefined;

let不存在变量提升,它所声明的变量一定要在声明之后使用,否则报错。

// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

三、可否被重复声明

var允许在相同作用域内,重复声明同一个变量;

let不允许在相同作用域内,重复声明同一个变量。

// 报错 Identifier 'a' has already been declared
function func() {
  let a = 10;
  var a = 1;
}

// 报错 Identifier 'a' has already been declared
function func() {
  let a = 10;
  let a = 1;
}

function func() {
  var a = 10;
  var a = 1;  //a:1
}

四、暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”这个区域,不再受外部影响。

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}
// 在let命令声明变量之前,都属于变量的“死区”

五、其它

const命令

const声明一个只读的变量,一旦声明,常量的值就不能改变。复杂类型指针指向的地址不能更改,内部数据可以更改。

const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.

const一旦声明变量,就必须立即初始化,不能等到以后再赋值。

const foo;
// SyntaxError: Missing initializer in const declaration

顶层对象的属性

顶层对象:浏览器环境(window对象),Node(global对象)

顶层对象的属性赋值与全局变量的赋值是同一件事。

var、function命令声明的全局变量,依旧是顶层对象的属性;

let、const、class声明的变量,不属于顶层对象的属性

var a = 1;
// 如果在 Node 的 REPL 环境,可以写成 global.a
// 或者采用通用方法,写成 this.a
window.a // 1

let b = 1;
window.b // undefined