更多前端文章
概述:變量可在聲明以前使用。前端
console.log(a);//正常運行,控制檯輸出 undefined var a = 1; console.log(b);//報錯,Uncaught ReferenceError: b is not defined let b = 1; console.log(c);//報錯,Uncaught ReferenceError: c is not defined const c = 1;
var 命令常常會發生變量提高現象,按照通常邏輯,變量應該在聲明以後使用纔對。爲了糾正這個現象,ES6 規定 let 和 const 命令不發生變量提高,使用 let 和 const 命令聲明變量以前,該變量是不可用的。主要是爲了減小運行時錯誤,防止變量聲明前就使用這個變量,從而致使意料以外的行爲。git
概述:若是在代碼塊中存在 let 或 const 命令,這個區塊對這些命令聲明的變量,從一開始就造成了封閉做用域。凡是在聲明以前就使用這些變量,就會報錯。es6
var tmp = 123; if (true) { tmp = 'abc';//報錯,Uncaught ReferenceError: tmp is not defined let tmp; }
剖析暫時性死區的原理,其實let/const一樣也有提高的做用,可是和var的區別在於github
let
不容許在相同做用域內,重複聲明同一個變量。數組
// 報錯 function func() { let a = 10; var a = 1; } // 報錯 function func() { let a = 10; let a = 1; } function func(arg) { let arg; } func() // 報錯 function func(arg) { { let arg; } } func() // 不報錯
在es5中咱們會遇到下面這寫狀況
第一種場景,內層變量可能會覆蓋外層變量。數據結構
var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = 'hello world';//沒有塊級做用域tmp變量提高到函數做用域裏致使tmp爲undefined } } f(); // undefined
第二種場景,用來計數的循環變量泄露爲全局變量。函數
var s = 'hello'; for (var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 5
上面代碼中,變量i
只用來控制循環,可是循環結束後,它並無消失,泄露成了全局變量。es5
let n = 5; if (true) { let n = 10; } console.log(n); // 5 }
let實際上爲 JavaScript 新增了塊級做用域。指針
一、const聲明變量的時候必須賦值,不然會報錯,一樣使用const聲明的變量被修改了也會報錯
二、const聲明變量不能改變,若是聲明的是一個引用類型,則不能改變它的內存地址code
const c ; //Uncaught SyntaxError: Missing initializer in const declaration const a= {a:1}; a.a=2; a={d:2};// Uncaught TypeError: Assignment to constant variable.
本質:const實際上保證的,並非變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,所以等同於常量。但對於複合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針,const只能保證這個指針是固定的(即老是指向另外一個固定的地址),至於它指向的數據結構是否是可變的,就徹底不能控制了
那麼咱們想獲得不可修改的const要怎麼作呢?應該使用Object.freeze
方法。
const foo = Object.freeze({}); // 常規模式時,下面一行不起做用; // 嚴格模式時,該行會報錯 foo.prop = 123; // 除了將對象自己凍結,對象的屬性也應該凍結。 var constantize = (obj) => { Object.freeze(obj); Object.keys(obj).forEach( (key, i) => { if ( typeof obj[key] === 'object' ) { constantize( obj[key] ); } }); };
參考文章
ECMAScript 6 入門