ES6 中的 let 與 const 命令

 

1.let命令

ES6 新增了let命令,用來聲明變量。它的用法類似於var,但是所聲明的變量,只在let命令所在的代碼塊內有效。

變量升級

var命令會發生”變量提升“現象,即變量可以在聲明之前使用,值爲undefined

爲了糾正這種現象,let命令改變了語法行爲,它所聲明的變量一定要在聲明後使用,否則報錯。

// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;

// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;

暫時性死區

 

只要塊級作用域內存在let命令,它所聲明的變量就“綁定”(binding)這個區域,不再受外部的影響。

var tmp = 123;

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

  let tmp;
  console.log(tmp); // undefined

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

不允許重複聲明

let不允許在相同作用域內,重複聲明同一個變量。

2.塊級作用域

 

ES5的作用域

ES5 只有全局作用域和函數作用域,沒有塊級作用域,這帶來很多不合理的場景。

第一種場景,內層變量可能會覆蓋外層變量。

var tmp = new Date();

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

f(); // undefined

第二種場景,用來計數的循環變量泄露爲全局變量。

var s = 'hello';

for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}

console.log(i); // 5

ES6的作用域

let實際上爲 JavaScript 新增了塊級作用域。

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

ES6 允許塊級作用域的任意嵌套,外層作用域無法讀取內層作用域的變量,內層作用域可以定義外層作用域的同名變量。

{{{{
  let insane = 'Hello World';
  {let insane = 'Hello World'}
}}}};

塊級作用域的出現,實際上使得獲得廣泛應用的立即執行函數表達式(IIFE)不再必要了。

// IIFE 寫法
(function () {
  var tmp = ...;
  ...
}());

// 塊級作用域寫法
{
  let tmp = ...;
  ...
}

塊級作用域與函數聲明

ES5 規定,函數只能在頂層作用域和函數作用域之中聲明,不能在塊級作用域聲明。

ES6 引入了塊級作用域,明確允許在塊級作用域之中聲明函數。ES6 規定,塊級作用域之中,函數聲明語句的行爲類似於let,在塊級作用域之外不可引用。

3.const命令

const聲明一個只讀的常量。一旦聲明,常量的值就不能改變。

const PI = 3.1415;
PI // 3.1415

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

const實際上保證的,並不是變量的值不得改動,而是變量指向的那個內存地址不得改動。

對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,因此等同於常量。

對於複合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指針,const只能保證這個指針是固定的,至於它指向的數據結構是不是可變的,就完全不能控制了。

const foo = {};

// 爲 foo 添加一個屬性,可以成功
foo.prop = 123;
foo.prop // 123

// 將 foo 指向另一個對象,就會報錯
foo = {}; // TypeError: "foo" is read-only

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章