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