let,const与var的比较

转载自阮一峰先生的ES6入门,稍有修正

1.基础概念MDN

var声清楚明了一个变量,而且能够同时初始化该变量。
let语句声明一个块级作用域的当地变量,而且可选的给予初始值。
const 声明建立一个只读的常量,作用域与let雷同。这不意味着常量指向的值不可变,而是变量标识符的值只能赋值一次。

2.基础用法

var为人人所熟习,在这里不再赘述。

let

let的用法类似于var,然则所声明的变量,只在let敕令地点的代码块内有用。

{  
  let a = 10;  
  var b = 1;  
}  
a // ReferenceError: a is not defined.  
b // 1

上面代码在代码块当中,分别用let和var声清楚明了两个变量。然后在代码块以外挪用这两 个变量,效果let声明的变量报错,var声明的变量返回了准确的值。这表明,let声明 的变量只在它地点的代码块有用。

for轮回的计数器,就很适宜运用let敕令。

for (let i = 0; i < 10; i++) {}

console.log(i);
//ReferenceError: i is not defined

上面代码中,计数器i只在for轮回体内有用,在轮回体外援用就会报错。

别的,for轮回另有一个特别之处,就是轮回语句部份是一个父作用域,而轮回体内部 是一个零丁的子作用域。

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

上面代码输出了3次abc,这表明函数内部的变量i和外部的变量i是星散的。

const

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

const PI = 3.1415;
PI // 3.1415

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

上面代码表明转变常量的值会报错。

const声明的变量不得转变值,这意味着,const一旦声明变量,就必须马上初始化,不能留到今后赋值。

const foo;
// SyntaxError: Missing initializer in const declaration
上面代码示意,关于const来讲,只声明不赋值,就会报错。

const的作用域与let敕令雷同:只在声明地点的块级作用域内有用。

3.变量声明提拔与暂时性死区

变量声明提拔MDN

此段仅实用var声明

由于变量声明(以及其他声明)老是在恣意代码实行之前处置惩罚的,所以在代码中的任
意位置声明变量老是等效于在代码开首声明。这意味着变量能够在声明之前运用,这
个行动叫做“hoisting”。“hoisting”就像是把一切的变量声明移动到函数或许全 局代码的开首位置。

bla = 2
var bla;
// ...
// 能够理解为:   
var bla;  
bla = 2; 由于这个缘由,我们发起老是在作用域的最最先(函数或许全局代码的开首)声明变 量。如许能够使变量的作用域变得清楚。 var敕令会发作”变量提拔“征象,即变量能够在声明之前运用,值为undefined。这类

征象多多少少是有些新鲜的,根据平常的逻辑,变量应该在声明语句以后才能够运用。

为了改正这类征象,let敕令转变了语法行动,它所声明的变量肯定要在声明后运用, 不然报错。

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

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

上面代码中,变量foo用var敕令声明,会发作变量提拔,即剧本最先运行时,变量foo 已存在了,然则没有值,所以会输出undefined。变量bar用let敕令声明,不会发作 变量提拔。这示意在声明它之前,变量bar是不存在的,这时候假如用到它,就会抛出一 个毛病。

const的作用域与let敕令雷同:只在声明地点的块级作用域内有用。

if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined

暂时性死区

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

var tmp = 123;

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

上面代码中,存在全局变量tmp,然则块级作用域内let又声清楚明了一个局部变量tmp,致使后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。

ES6明确划定,假如区块中存在let和const敕令,这个区块对这些敕令声明的变量,从一最先就形成了关闭作用域。通常在声明之前就运用这些变量,就会报错。

总之,在代码块内,运用let敕令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

if (true) {
  // TDZ最先
  tmp = 'abc'; // ReferenceError
  console.log(tmp); // ReferenceError

  let tmp; // TDZ完毕
  console.log(tmp); // undefined

  tmp = 123;
  console.log(tmp); // 123
}

上面代码中,在let敕令声明变量tmp之前,都属于变量tmp的“死区”。

“暂时性死区”也意味着typeof不再是一个百分之百平安的操纵。

typeof x; // ReferenceError
let x;
上面代码中,变量x运用let敕令声明,所以在声明之前,都属于x的“死区”,只需用到该变量就会报错。因而,typeof运行时就会抛出一个ReferenceError。

作为比较,假如一个变量基础没有被声明,运用typeof反而不会报错。

typeof undeclared_variable // “undefined”
上面代码中,undeclared_variable是一个不存在的变量名,效果返回“undefined”。所以,在没有let之前,typeof运算符是百分之百平安的,永久不会报错。如今这一点不成立了。如许的设想是为了让人人养成优越的编程习气,变量肯定要在声明以后运用,不然就报错。

别的,下面的代码也会报错,与var的行动差别。

// 不报错
var x = x;

// 报错
let x = x;
// ReferenceError: x is not defined

上面代码报错,也是由于暂时性死区。运用let声明变量时,只需变量在还没有声明完成前运用,就会报错。上面这行就属于这个状况,在变量x的声明语句还没有实行完成前,就去取x的值,致使报错”x 未定义“。

ES6 划定暂时性死区和let、const语句不涌现变量提拔,重要是为了削减运行时毛病,防备在变量声明前就运用这个变量,从而致使意料以外的行动。如许的毛病在 ES5 是很罕见的,如今有了这类划定,防止此类毛病就很轻易了。

总之,暂时性死区的实质就是,只需一进入当前作用域,所要运用的变量就已存在了,然则不可猎取,只要比及声明变量的那一行代码涌现,才能够猎取和运用该变量。

4.反复声明

var是许可在雷同作用域内反复声明同一个变量的,而let与const不许可这一征象。

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

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

因而,不能在函数内部从新声明参数。

function func(arg) {
  let arg; // 报错
}

function func(arg) {
  {
    let arg; // 不报错
  }
}

const声明的常量,也与let一样不可反复声明。

var message = "Hello!";
let age = 25;

// 以下两行都邑报错
const message = "Goodbye!";
const age = 30;
    原文作者:koucxz
    原文地址: https://segmentfault.com/a/1190000008734811
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞