let霜威、const 是 ES6 新增的兩個聲明變量的命令谈喳,用法類似于于 var。
塊級作用域
眾所周知戈泼,在 ES5 當中婿禽,只有全局作用域
和函數作用域
。那為什么需要塊級作用域
呢矮冬?
-
場景一:內層同名變量會覆蓋外層變量
var str = "hello,world!"; function fun() { console.log(str); var str = "你好谈宛,世界"; } fun(); // undefined var str = "hello,world!"; function fun() { console.log(str); let str = "你好,世界"; } fun(); // ReferenceError
-
場景二:循環(huán)變量泄露為全局變量
for (var i = 0; i < 5; i++) { setTimeout(() => { console.log(i); }, 1000); } // 5 5 5 5 5 for (let i = 0; i < 5; i++) { setTimeout(() => { console.log(i); }, 1000); } // 1 2 3 4 5
在ES5胎署,我們在通常會使用匿名立即執(zhí)行函數解決這類問題
for (var i = 0; i < 5; i++) { (function (i) { setTimeout(() => { console.log(i); }, 1000); })(i) } // 1 2 3 4 5
let
let 實際上是 ES6 新增的塊級作用域吆录,和var相比,有以下特征
不存在變量提升
var 聲明的變量會提升到當前作用域的最頂端琼牧,注意只提升聲明恢筝,不提升賦值哀卫。
console.log(str); // undefined
var str = "javascript";
等價于;
var str;
console.log(str);
str = "javascript";
let 不存在變量提升
console.log(str); // ReferenceError
let str = "javascript";
暫時性死區(qū)
只要是 let 聲明的變量會“綁定”到當前作用域,不會受外部影響撬槽,在代碼塊內此改,使用 let 命令聲明變量之前,該變量都是不可用的侄柔。這在語法上共啃,稱為“暫時性死區(qū)”,總之暂题,暫時性死區(qū)的本質就是移剪,<strong>只要一進入當前作用域,所要使用的變量就已經存在了薪者,但是不可獲取纵苛,只有等到聲明變量的那一行代碼出現,才可以獲取和使用該變量</strong>言津。
var tmp = 123;
if (true) {
tmp = "abc"; // ReferenceError
let tmp;
}
不允許重復聲明
let 不允許同一作用域內重復聲明同一個變量攻人,var可以重復聲明。
var str;
var str; // 可以
var str;
let str; //報錯
let str1悬槽;
let str1; //報錯
因此怀吻,函數內部不能使用let重復聲明參數
function fun(str) {
var str = "222"
console.log(str);
}
fun("111"); // 222
function fun(str) {
let str = "222"
console.log(str);
}
fun("111"); // 報錯
不屬于window屬性
var、function屬于全局變量初婆,是頂層對象的屬性烙博,let、const烟逊、class 不屬于頂層對象屬性,不可通過window.去訪問
const
const 聲明一個只讀的常量铺根,一旦被聲明就不允許改變宪躯。
const str = "str"
str = "str" // 報錯
const和let一樣聲明只在塊級作用域有效,同樣沒有變量提升位迂,和存在暫時性死區(qū)访雪,也不可重復聲明
const的本質
我們都知道,基本類型數據存在棧內存中掂林,引用類型數據只是在棧內存存儲了一個指向堆內存的指針臣缀,實際數據存放在堆內存中。
const并不是保證這個變量不可以改變泻帮,而是保證這個變量指向的占內存的值不可改變精置,所以使用const創(chuàng)建引用類型數據要小心
const arr = [];
arr.push(1) // 可以
arr = 1 // 報錯
如果想將一個對象凍結的話,可以使用Object.freeze
方法
const foo = Object.freeze({});
// 常規(guī)模式時锣杂,面一行不起作用脂倦;
// 嚴格模式時番宁,該行會報錯
foo.prop = 123;