let
和const
是 ES6 新增的命令,用於聲明變量,這兩個命令跟 ES5 的var
有許多不一樣,而且let
和const
也有一些細微的不一樣,再認真閱讀了阮一峯老師的文檔後,發現仍是有一些不知道的細節...前端
博客、 前端積累文檔、 公衆號、 GitHub
var
和let
/const
的區別node
const
命令兩個注意點:git
ES5只有全局做用域和函數做用域,沒有塊級做用域。es6
這帶來不少不合理的場景:github
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]); // i應該爲這次for循環使用的變量 } console.log(i); // 5 全局範圍均可以讀到
function f1() { let n = 5; if (true) { let n = 10; console.log(n); // 10 內層的n } console.log(n); // 5 當前層的n }
{{{{ {let insane = 'Hello World'} console.log(insane); // 報錯 讀不到子做用域的變量 }}}};
{ let a = ...; ... } { let a = ...; ... }
以上形式,能夠用於測試一些想法,不用擔憂變量重名,也不用擔憂外界干擾web
在塊級做用域聲明函數,由於瀏覽器的要兼容老代碼,會產生一些 問題!
在塊級做用域聲明函數,最好使用匿名函數的形式。數組
if(true){ let a = function () {}; // 做用域爲塊級 令聲明的函數做用域範圍更清晰 }
ES6 的塊級做用域容許聲明函數的規則,只在使用大括號的狀況下成立,若是沒有使用大括號,就會報錯。瀏覽器
// 報錯 'use strict'; if (true) function f() {} // 咱們須要給if加個{}
變量提高的現象:在同一做用域下,變量能夠在聲明以前使用,值爲 undefined安全
ES5 時使用var
聲明變量,常常會出現變量提高的現象。babel
// var 的狀況 console.log(foo); // 輸出undefined var foo = 2; // let 的狀況 console.log(bar); // 報錯ReferenceError let bar = 2;
只要一進入當前做用域,所要使用的變量就已經存在了,可是不可獲取,只有等到聲明變量的那一行代碼出現,才能夠獲取和使用該變量
var tmp = 123; // 聲明 if (true) { tmp = 'abc'; // 報錯 由於本區域有tmp聲明變量 let tmp; // 綁定if這個塊級的做用域 不能出現tmp變量 }
暫時性死區和不能變量提高的意義在於:
爲了減小運行時錯誤,防止在變量聲明前就使用這個變量,從而致使意料以外的行爲。
在測試時出現這種狀況:
var a= '聲明';const a = '不報錯'
,這種狀況是由於babel在轉化的時候,作了一些處理,在瀏覽器的控制檯中測試,就成功報錯
let
、const
不容許在相同做用域內,重複聲明同一個變量
function func(arg) { let arg; // 報錯 } function func(arg) { { let arg; // 不報錯 } }
window
global
var a = 1; // 若是在 Node環境,能夠寫成 global.a // 或者採用通用方法,寫成 this.a window.a // 1 let b = 1; window.b // undefined
一旦聲明,必須立刻賦值
let p; var p1; // 不報錯 const p3 = '立刻賦值' const p3; // 報錯 沒有賦值
const一旦聲明值就不能改變
const p = '不能改變'; p = '報錯'
考慮以下狀況:
const p = ['不能改動'] const p2 = { name: 'OBKoro1' } p[0] = '不報錯' p2.name = '不報錯' p = ['報錯'] p2 = { name: '報錯' }
const所說的一旦聲明值就不能改變,實際上指的是:變量指向的那個內存地址所保存的數據不得改動
const
只能保證指針是固定的(老是指向同一個地址),它內部的值是能夠改變的(不要覺得const就安全了!)因此只要不從新賦值整個數組/對象, 由於保存的是一個指針,因此對數組使用的push
、shift
、splice
等方法也是容許的,你就是把值一個一個全都刪光了都不會報錯。
> 複雜類型還有函數,正則等,這點也要注意一下。
再總結一下,看到這些名詞,腦子裏應該會有對應的理解,若是沒有的話,那能夠再看看對應的內容。
var
和let
/const
的區別:const
命令兩個注意點:let
能夠先聲明稍後再賦值,而const
在 聲明以後必須立刻賦值,不然會報錯let
使用場景:變量,用以替代var
。const
使用場景:常量、聲明匿名函數、箭頭函數的時候。以爲還不錯的話,給個人項目點個star吧
參考資料: