更多前端文章前端
概述:變量可在聲明以前使用。git
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 命令聲明變量以前,該變量是不可用的。主要是爲了減小運行時錯誤,防止變量聲明前就使用這個變量,從而致使意料以外的行爲。es6
概述:若是在代碼塊中存在 let 或 const 命令,這個區塊對這些命令聲明的變量,從一開始就造成了封閉做用域。凡是在聲明以前就使用這些變量,就會報錯。github
var tmp = 123;
if (true) {
tmp = 'abc';//報錯,Uncaught ReferenceError: tmp is not defined
let tmp;
}
複製代碼
剖析暫時性死區的原理,其實let/const一樣也有提高的做用,可是和var的區別在於數組
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
複製代碼
第二種場景,用來計數的循環變量泄露爲全局變量。ui
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 新增了塊級做用域。spa
一、const聲明變量的時候必須賦值,不然會報錯,一樣使用const聲明的變量被修改了也會報錯 二、const聲明變量不能改變,若是聲明的是一個引用類型,則不能改變它的內存地址
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 入門