乐趣区

关于es6:ES6之let和const的区别

前言

ES6 新增了 let 命令,用来申明变量。它的用法相似于 varconst 申明一个只读的常量。一旦申明,常量的值就不能扭转。

let:申明的是变量

一、不存在变量晋升

var命令会产生“变量晋升”景象,即变量能够在申明之前应用,值为undefined。这里就不具体说这个货色,有须要的能够看我 详解 javascript 变量晋升 这个文章。

为了纠正这种景象,let命令扭转了语法行为,它所申明的变量肯定要在申明后应用,否则报错。

// var 的状况
alert(foo); // 输入 undefined
var foo = 2;

// let 的状况
alert(bar); // 报错 ReferenceError
let bar = 2;

下面代码中,变量 foovar命令申明,会产生变量晋升,即脚本开始运行时,变量 foo 曾经存在了,然而没有值,所以会输入 undefined。变量barlet命令申明,不会产生变量晋升。这示意在申明它之前,变量 bar 是不存在的,这时如果用到它,就会抛出一个谬误

二、暂时性死区,先申明在应用

应用 let 命令申明变量之前,该变量都是不可用的。

var num = 123;

if (true) {
  num = 'abc'; // ReferenceError
  let num;
}

三、不容许反复申明

let不容许在雷同作用域内,反复申明同一个变量。

// 报错
function fn() {
  let a = 10;
  var a = 5;
}

// 报错
function fn() {
  let a = 10;
  let a = 5;
}

四、块级作用域

ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。

第一种场景,内层变量可能会笼罩外层变量。

var tmp = '你好';
function f() {console.log(tmp);
  if (false) {var tmp = 'hello world';}
}
f(); // undefined

下面代码的原意是,if代码块的内部应用外层的 tmp 变量,外部应用内层的 tmp 变量。然而,函数 f 执行后,输入后果为 undefined,起因在于变量晋升,导致内层的tmp 变量笼罩了外层的 tmp 变量。

ES6 的块级作用域,let 实际上为 javascript 新增的块级作用域。

function f1() {
  let n = 20;
  if (true) {let n = 10;}
  console.log(n); // 20
}

下面的函数有两个代码块,都申明了变量 n,运行后输入 20。这示意外层代码块不受内层代码块的影响。如果两次都应用var 定义变量n,最初输入的值才是 10。

const: 常量

const申明一个只读的常量。一旦申明,常量的值就不能扭转。

const PI = 3.1415;
PI // 3.1415

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

下面代码表明扭转常量的值会报错。

const的作用域与 let 命令雷同:只在申明所在的块级作用域内无效
const 命令申明的常量也是不晋升,同样存在暂时性死区,只能在申明的地位前面应用。
const申明的常量,也与 let 一样不可反复申明。

const foo = {};

// 为 foo 增加一个属性,能够胜利
foo.prop = 123;
foo.prop // 123

// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

下面代码中,常量 foo 贮存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把 foo 指向另一个地址,但对象自身是可变的,所以仍然能够为其增加新属性。

let 和 const 的相同点:

只在申明所在的块级作用域内无效。
不会产生晋升,同时存在暂时性死区,只能在申明的地位前面应用。
不可反复申明。

let 和 const 的不同点:

let 申明的变量能够扭转,值和类型都能够扭转;const 申明的常量不能够扭转,这意味着,const 一旦申明,就必须立刻初始化,不能当前再赋值
数组和对象等复合类型的变量,变量名不指向数据,而是指向数据所在的地址。const 只保障变量名指向的地址不变,并不保障该地址的数据不变,所以将一个复合类型的变量申明为常量必须十分小心。

退出移动版