ES6 裏新增了兩種聲明變量的方式,let 和 const,加上原來的 var,一共就有三種方式來聲明變量了。那到底該用哪一個呢?關於「儘量不用 var」 這一點,你們應該沒有什麼意見分歧(其實仍是有少數人不這麼想的),關於「是用 let 仍是用 const」,社區裏主要有兩種不一樣的觀點:html
1. 默認全用 let,只在符合一些寫代碼的人的主觀判斷條件的時候用 const,下面舉個這樣的「主觀判斷條件」的例子(實際代碼中用到 const 的概率大概會是 0.1%):數組
代碼舉例:函數
const VERSION = 2 const TIMEOUT = 10000 const MB = 1024 * 1024 const DAY = 24 * 60 * 60 * 1000 const COLOR = "rgb(255,255,255)" const HTMLNS = "http://www.w3.org/1999/xhtml" const BUTTONS = ["left", "middle", "right"] const SIDES = ["left", "right", "top", "bottom"]
2. 默認全用 const,只有該變量須要被從新賦值才用 let (實際代碼中用到 const 的概率大概會是 95%),和上面舉的三個主觀判斷條件對比一下差別:工具
第一種用法是很是主觀的,好比你用 const 的判斷條件有可能就和我上面舉的不同,好比你也許以爲局部變量也能夠用 const ?或者你覺的數組和對象是可變的值,怎麼能用 const 呢?由於很主觀,因此一個團隊的代碼風格很難達成一致,甚至只有你一我的維護的代碼,const 的用法在不一樣的時間內也沒有統一的規律,由於可能連你本身都沒有明確的想過:「何時我應該用 const」,說白了就是「看心情」。而第二種用法是很是客觀的,簡單直接,沒有含糊不清的地方,若是採用這種用法,至少團隊代碼風格的統一是不成問題的。測試
ES6 以前你有沒有寫過或者見過相似下面這樣的代碼:ui
var ids = document.getElementById("ids").value // 多個 id 組成的字符串,好比 "100 101 102" ids = ids.split(" ") // 拆分紅數組 ids.forEach(...
ids 這個變量的類型從字符串變成了數組,但變量名卻沒變(寫代碼的人懶的想新名字),這被認爲是一種很差的編碼風格。若是有「默認都用 const」的風格約定(第一行已經寫了 const ids),會迫使寫代碼的人在第二行想一個新的變量名(固然他也有可能把一行的 const 改爲 let),而默認用 let 的風格不會讓人有種迫使感(固然用 let 的人也可能根本不須要迫使感就會主動想一個新的名字,看人)。this
除了上面說的這兩個「默認用 const」 的優勢,還有人說默認用 const 比用 let 能讓代碼更有可讀性,更語義:讀代碼的人看一個變量的聲明方式就知道它在下面會不會被從新賦值。但這些都是從代碼風格上說事的,代碼風格是很主觀的一個東西,有人覺的好,有人並不覺的很差,你很難拿着這樣的優勢去說服默認用 let 的人。好比他們可能會回擊說:「咱們團隊有詳細的風格指南,規定了何時用 const,代碼風格統一不是問題」(第一個優勢沒了);「一樣是有風格指南,咱們團隊的人不會複用不應複用的變量名」(第二個優勢沒了);「let 比 const 短」(你反而無言以對,被擊敗)。編碼
有沒有更有說服力的優勢呢,好比能不能舉個「默認用 const 可以避免,而默認用 let 避免不了的 bug」 的代碼實例呢?下面我構思了一個:spa
let path = require("path") // 這裏 path 是個全局變量 /* 這裏有不少代碼 */ function bar() { let path = "." // 這裏 path 是個局部變量 /* 這裏有不少代碼 */ if (this.isInProduction) { // 只在生產環境中執行的代碼 path = "~" // 爲局部變量 path 從新賦值 } /* 使用局部變量 path 的代碼 */ }
假設這是一段運行正常的代碼, path 是個全局變量,同時又是個 bar 函數的局部變量。某天有人重構 bar 函數的時候認爲 path 這個局部變量起的很差,和全局變量衝突了,應該換了個名字,而後把 bar 函數裏面聲明 path 的地方和使用 path 的地方的 path 都替換成了 filePath,但不當心漏掉了 path = "~" 這一行裏的 path,本地測試沒問題,上線出了故障,好心辦了壞事啊。設計
若是這個全局變量 path 是用 const 定義的話。。。也並不能發現這個 bug。爲何呢,請看個人上篇文章,是由於關於 const,ES6 有個設計缺陷,就是爲 const 變量從新賦值不是個靜態錯誤。可是若是你同時使用了 ESLint 並開啓了 no-const-assign 規則,這個線上問題就能被扼殺在萌芽狀態:
總結:默認用 const 能夠帶來一些代碼風格上的好處,若是配合 Lint 工具還能夠避免某些意外的 bug,但若是不使用 Lint 工具,相反可能會形成一些意外的 bug(好比上篇文章中開頭舉的)。不論是可能形成的 bug,仍是可能避免的 bug,都是些 edge case,並不常見,因此很大程度上,選擇默認用 const 仍是 let 還是一件很主觀的事。
ES6 的編輯 Allen Wirfs-Brock 曾說過,若是能重來一次,他但願把 let 設計成像如今的 const 同樣,而新增一個好比 let var 代替如今的 let。但由於 const 這個保留字在 JS 剛發明的時候就從 Java 抄過來了,let/const 這對兒關鍵字在制定 ES5 的時候就計劃在 ES6 裏用了,因此 ES6 裏也就沒再改了。