【探祕ES6】系列專欄(十二):let和const

ES6做爲新一代JavaScript標準,已正式與廣大前端開發者見面。爲了讓你們對ES6的諸多新特性有更深刻的瞭解,Mozilla Web開發者博客推出了《ES6 In Depth》系列文章。CSDN已獲受權,將持續對該系列進行翻譯,組織成【探祕ES6】系列專欄,供你們學習借鑑。本文爲該系列的第十二篇。
前端

本文介紹的是有關let和const關鍵字的使用。 node

對於JS而言,開發者有可能遇到如下兩個問題。 es6

問題一:區塊不等同於做用域。 web

在一個JS函數中聲明的變量的做用域是在整個函數裏,由此將會引起兩個問題。 函數

第一個是區塊裏定義的變量的做用域不只限於區塊,而是做用於整個函數中。請看如下例子,裏面定義的變量是t: 工具

function runTowerExperiment(tower, startTime) {
  var t = startTime;
  tower.on("tick", function () {
    ... code that uses t ...
  });
  ... more code ...
}

若是要增長一個用於檢測保齡球速度的功能,可能會這樣寫:  學習

function runTowerExperiment(tower, startTime) {
  var t = startTime;
  tower.on("tick", function () {
    ... code that uses t ...
    if (bowlingBall.altitude() <= 0) {
      var t = readTachymeter();
      ...
    }
  });
  ... more code ...
}

如今問題來了,咱們不自覺地添加了一個同名變量 t ;而這個 t 的做用域會發生改變,再也不是第一次定義時的t了。可見,JS中的變量相似於Photoshop中的油漆桶工具,至聲明開始能夠向前或向後做用直到碰到函數邊界,咱們稱之爲「擡升」。這個例子中擡升致使的結果是,以 t 爲計算對象的結果會產生NaN。 編碼

問題二:變量在循環體中的共享 spa

請先看下面:  .net

var messages = ["Hi!", "I'm a web page!", "alert() is fun!"];
for (var i = 0; i < messages.length; i++) {
  alert(messages[i]);
}

這段代碼的運算結果是顯而易見的,可是若是換成下面這種方式呢? 

var messages = ["Meow!", "I'm a talking cat!", "Callbacks are fun!"];
for (var i = 0; i < messages.length; i++) {
  setTimeout(function () {
    cat.say(messages[i]);
  }, i * 1500);
}

其結果會是怎麼樣?詳見 完整示例

結果是連續三個undefined?!緣由就是變量的共享問題。僅有的變量 i 被循環體以及全部timeout回調共享了,其結果就是當循環結束時i=3,因此使用messages[3]做爲輸出會顯示undefined,由於沒有定義這個元素。若是要解決這個問題,有好幾種方法,詳見 連接 

使用let代替var

爲了解決向後兼容的編碼問題,Brendan Eich引入了關鍵字let。當你要進行全局搜索的時候,若是以前使用var來定義變量,那麼會致使編碼不能連續。因此在ES6裏,請嘗試使用let而不是var。

這二者的主要區別是:

  • let變量是區域變量:let定義的變量僅限於局部區塊內,而不是整個函數體內。因此使用let就可避免前述的變量共享問題。

  • 全局let變量不是全局對象的屬性:也就是說,你不能使用window.variableName的方式來使用它們。相反,它們的活動範圍是在於Web頁面下的非可視JS代碼區塊內。

  • for(let x…)形式的循環在遍歷時會產生新的x:這是一個很美妙的地方。它是意思是若是一個for (let...)循環中包含結束,例如前述的talking cat例子,那麼每一個結束會獲得不一樣的變量輸出,而不是都使用相同的變量。因此也就解決了變量共享的問題。此外,該特性對for-of,for-in都是適用的。

  • 在使用let聲明變量前使用變量會出錯:例如這些編寫的話,將會出現引用錯誤: 

  • function update() {
      console.log("current time:", t);  // ReferenceError
      ...
      let t = readTachymeter();
    }
  • 重複使用let聲明變量會致使語法錯誤。

該約束是能幫忙檢查出一些粗枝大葉的問題。

使用const

相似於其它語言,ES6中可以使用const進行常量定義;若是嘗試對已經定義的常量進行賦值,將會引發語法錯誤:

const MAX_CAT_SIZE_KG = 3000; // 
MAX_CAT_SIZE_KG = 5000; // SyntaxError
MAX_CAT_SIZE_KG++; // nice try, but still a SyntaxError

一樣地,定義的同時不對常量賦值也是一個語法錯誤:

const theFairest;  // SyntaxError, you troublemaker

如何啓用let和const?

請使用ES6編譯器,例如Babel,Traceur或者TypeScript。io.js可在strict模式下使用;node.js與之相似,可是須要啓用harmony選項。

原文連接:ES6 In Depth: let and const

(譯者:伍昆,責編:陳秋歌)

本譯文遵循Creative Commons Attribution Share-Alike License v3.0 

相關文章
相關標籤/搜索