一、let命令
- 不存在變量提升捧书。es5的
var
會(huì)存在變量提升問題苛吱,但是es6的let
和const
不會(huì)存在變量提升問題酪术。
- 暫時(shí)性死區(qū)。只要在塊級(jí)作用域內(nèi)存在
let
命令翠储,它所聲明的變量就綁定在這個(gè)區(qū)域绘雁,不再受外部的影響。es6明確規(guī)定援所,如果區(qū)塊中存在let
和const
命令庐舟,這個(gè)區(qū)塊對(duì)這些命令聲明的變量,從一開始就形成了封閉作用域任斋,凡是在聲明之前就使用這些變量继阻,就會(huì)報(bào)錯(cuò)。即使是使用typeof
也會(huì)報(bào)錯(cuò)废酷。
var tmp = 123;
if(true){
tmp = "abc"; //ReferenceError tmp is not defined
let tmp;
}
- 不允許重復(fù)聲明瘟檩。
let
和const
不允許在相同的作用域內(nèi),重復(fù)聲明同一個(gè)變量澈蟆。
// 報(bào)錯(cuò)
function func() {
let a = 10;
var a = 1;
}
// 報(bào)錯(cuò)
function func() {
let a = 10;
let a = 1;
}
//不能在函數(shù)內(nèi)部重新聲明參數(shù)
function func(arg) {
let arg; // 報(bào)錯(cuò)
}
function func(arg) {
{
let arg; // 不報(bào)錯(cuò)
}
}
二墨辛、塊級(jí)作用域
- es5只有全局作用域和函數(shù)作用域,沒有塊級(jí)作用域趴俘。這可能導(dǎo)致很多不合理的場(chǎng)景睹簇。
//內(nèi)層變量可能會(huì)覆蓋外層變量
var tmp = 123;
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
//用來計(jì)數(shù)的循環(huán)變量泄露為全局變量
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
- es6的塊級(jí)作用域
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
- es6允許塊級(jí)作用域的任意嵌套奏赘,塊級(jí)作用域的出現(xiàn),使得廣泛應(yīng)用的立即執(zhí)行函數(shù)表達(dá)式(IIFE)不再必要太惠,塊級(jí)作用域不返回值磨淌,除非它是全局變量。
// IIFE 寫法
(function () {
var tmp = ...;
...
}());
// 塊級(jí)作用域?qū)懛?{
let tmp = ...;
...
}
三凿渊、const命令
-
const
聲明一個(gè)只讀的常量梁只,一旦聲明,常量的值就不能改變埃脏。
-
const
一旦聲明變量搪锣,就必須立即初始化,不能留到以后賦值彩掐。
-
const
限定的是賦值行為构舟。
const a = 1;
a = 2;//報(bào)錯(cuò)
const arr = [];
arr.push(1) //[1]
//在聲明引用型數(shù)據(jù)為常量時(shí),const保存的是變量的指針堵幽,只要保證指針不變就不會(huì)保存狗超。下面的行為就會(huì)報(bào)錯(cuò)
arr = [];//報(bào)錯(cuò) 因?yàn)槭琴x值行為。變量arr保存的指針改變了谐檀。
四抡谐、頂層對(duì)象屬性與全局變量
- 頂層對(duì)象,在瀏覽器環(huán)境指的是
window
對(duì)象桐猬,在 node 指的是global
對(duì)象。ES5 之中刽肠,頂層對(duì)象的屬性與全局變量是等價(jià)的溃肪。
window.a = 1;
a // 1
a = 2;
window.a // 2
- es6中引入的
let
、const
音五、class
聲明的全局變量不再屬于頂層對(duì)象的屬性惫撰。但是var
、function
聲明的變量依然屬于全局對(duì)象的屬性躺涝。
var a = 1;
window.a // 1
let b = 1;
window.b // undefined