let命令和const命令的使用注意事項(xiàng)

本文大量參考阮一峰老師ES6手冊(cè)魔市。

先是let的使用注意事項(xiàng)

let只在所在的代碼塊以及更深的代碼塊內(nèi)有效

通常就是花括號(hào)包起來(lái)的代碼塊房资,形成的作用域叫塊級(jí)作用域淘这。

if (true) {
    let a = 1;
    if (true) {
        a = 2;
        console.log(a); // 2
    }
    console.log(a); // 2
}

比較特別的for循環(huán)

for循環(huán)還有一個(gè)特別之處穴张,就是設(shè)置循環(huán)變量的那部分是一個(gè)父作用域掉伏,而循環(huán)體內(nèi)部是一個(gè)單獨(dú)的子作用域缝呕。

所以澳窑,for (var i = 0; i < 10; i++)for (let i = 0; i < 10; i++)就有區(qū)別,下面栗子可以證明:

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

我們知道供常,函數(shù)只有被調(diào)用的時(shí)候才會(huì)去考慮作用域摊聋,而且js的作用域特點(diǎn)是詞法作用域,所以:

第一段代碼栈暇,打印10是因?yàn)?code>i是全局變量麻裁,當(dāng)調(diào)用a[6]的時(shí)候i就是10,所以打印10沒(méi)毛病源祈。

第二段代碼煎源,a[6]console.log(i)會(huì)去找ii既然是由let聲明香缺,就被禁錮在for作用域內(nèi)手销,而且for循環(huán)10次能產(chǎn)生10個(gè)作用域,所以i在那個(gè)作用域的值是6图张,于是打印6锋拖。

不變量提升

這個(gè)特性的優(yōu)點(diǎn)我認(rèn)為是:符合人腦思維:先聲明,后使用埂淮。沒(méi)聲明就使用的話姑隅,會(huì)報(bào)錯(cuò)写隶,更醒目倔撞,程序員更容易糾錯(cuò)。就像下面這樣:

// var 的情況
console.log(foo); // 輸出undefined慕趴,不報(bào)錯(cuò)
var foo = 2;

// let 的情況
console.log(bar); // 報(bào)錯(cuò)ReferenceError
let bar = 2;

要我說(shuō)痪蝇,其實(shí)這個(gè)特性沒(méi)什么大用。盡早聲明變量應(yīng)該是寫代碼的起碼規(guī)范冕房。

“暫時(shí)性死區(qū)”(temporal dead zone躏啰,簡(jiǎn)稱 TDZ)

這個(gè)現(xiàn)象是老外提出來(lái)的,但我并沒(méi)有看出它跟“不變量提升”有什么區(qū)別耙册。死區(qū)的原因不就是“變量不提升”+“塊級(jí)作用域”么给僵?

不變量提升也好,暫時(shí)性死區(qū)也好详拙,都是強(qiáng)迫程序員寫出更規(guī)范的代碼帝际,就認(rèn)為是嚴(yán)格模式就得了。

不允許重復(fù)聲明

這個(gè)跟var確實(shí)有鮮明對(duì)比饶辙。

簡(jiǎn)單一句話:銅鑼灣只能有一個(gè)浩南6拙鳌(如果出了銅鑼灣那就隨便了)

if (true) {
    let a = 1;
    if (true) {
        let a = 2;
        console.log(a); // 2
    }
    console.log(a); // 1
}

上面代碼如果把兩個(gè)let改成var,那么會(huì)輸出兩個(gè)2弃揽,就是因?yàn)関ar允許重復(fù)聲明脯爪。

塊級(jí)作用域

塊級(jí)作用域的優(yōu)點(diǎn):

  1. 模塊化編程则北。
  2. 不需要特意寫一個(gè)自執(zhí)行函數(shù)來(lái)制造一個(gè)局部作用域。

到底能不能在塊級(jí)作用域聲明函數(shù)痕慢?

ES5是不允許的尚揣,但是ES6又允許了。本著兼容原則守屉,最好是別這么干惑艇,也就是不要在塊級(jí)作用域聲明函數(shù)。如果必須要在塊代碼里寫函數(shù)拇泛,就用函數(shù)表達(dá)式滨巴。

到底啥時(shí)候用var,啥時(shí)候用let俺叭?

var和let各自的適用場(chǎng)合:

  1. 為了兼容低版本IE恭取,當(dāng)然用var。除此之外熄守,優(yōu)先用let蜈垮。
  2. 有人說(shuō),es6中用let裕照,babel中用var攒发,原因是babel會(huì)寫很多墊片代碼實(shí)現(xiàn)對(duì)let的支持,從代碼量來(lái)講得不償失晋南。

以下是const的注意事項(xiàng)

const跟let特性一致的地方

  1. 塊級(jí)作用域
  2. 不提升
  3. 不可重復(fù)聲明(重復(fù)聲明跟再次賦值是兩碼事)
  4. 即使在全局作用域聲明惠猿,也不會(huì)是window對(duì)象的屬性

跟let特性的區(qū)別

就一條,let雖然不能重復(fù)聲明负间,但是可以無(wú)限制的賦值偶妖,但const只能初始化的時(shí)候賦值一次。

到底啥時(shí)候用let政溃,啥時(shí)候用const趾访?

一句話:const永遠(yuǎn)優(yōu)先原則。

  1. 在全局環(huán)境董虱,不應(yīng)該設(shè)置變量扼鞋,只應(yīng)設(shè)置常量》哂眨可能你有顧慮是我真的想讓一個(gè)量被修改云头,又真的想讓它在全局環(huán)境,怎么辦转锈?這種情況下盘寡,可以用這種方式:
const globelConst = {a: 1, b: 2}; // a和b的值確實(shí)是可以改變的,原因見(jiàn)下文
  1. 在局部環(huán)境撮慨,也應(yīng)該優(yōu)先考慮使用const竿痰,除非它真的需要改變值脆粥,那么就用let。

小心賦值復(fù)合類型數(shù)據(jù)

對(duì)于簡(jiǎn)單類型的數(shù)據(jù)(數(shù)值影涉、字符串变隔、布爾值),const的值是絕對(duì)不會(huì)變的蟹倾,因?yàn)樽兞恐赶虮4嬖谔囟▋?nèi)存地址的數(shù)據(jù)匣缘。但對(duì)于復(fù)合類型的數(shù)據(jù)(主要是對(duì)象和數(shù)組),變量指向的是對(duì)應(yīng)內(nèi)存地址的指針鲜棠,const只能保證這個(gè)指針是唯一的指針肌厨,至于它指向的數(shù)據(jù)結(jié)構(gòu)是不是可變的,就完全不能控制了豁陆。因此柑爸,將一個(gè)數(shù)組或者對(duì)象聲明為常量必須非常小心。

如果想要真正凍結(jié)一個(gè)數(shù)組或者對(duì)象盒音,可以用Object.freeze方法表鳍。

const foo = Object.freeze({});

// 常規(guī)模式時(shí),下面一行不起作用祥诽;
// 嚴(yán)格模式時(shí)譬圣,該行會(huì)報(bào)錯(cuò)
// 總之是不能用
foo.prop = 123;

但是這個(gè)方法只能淺凍結(jié),如果想深凍結(jié)雄坪,就得寫個(gè)方法:

var deepFreeze = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, i) => {
    if ( typeof obj[key] === 'object' ) {
      deepFreeze( obj[key] );
    }
  });
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末厘熟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子诸衔,更是在濱河造成了極大的恐慌盯漂,老刑警劉巖颇玷,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笨农,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡帖渠,警方通過(guò)查閱死者的電腦和手機(jī)谒亦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)空郊,“玉大人份招,你說(shuō)我怎么就攤上這事∧酰” “怎么了锁摔?”我有些...
    開(kāi)封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)哼审。 經(jīng)常有香客問(wèn)我谐腰,道長(zhǎng)孕豹,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任十气,我火速辦了婚禮励背,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘砸西。我一直安慰自己叶眉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布芹枷。 她就那樣靜靜地躺著衅疙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鸳慈。 梳的紋絲不亂的頭發(fā)上炼蛤,一...
    開(kāi)封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音蝶涩,去河邊找鬼理朋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绿聘,可吹牛的內(nèi)容都是我干的嗽上。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼熄攘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼兽愤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起挪圾,我...
    開(kāi)封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤浅萧,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后哲思,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體洼畅,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年棚赔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了帝簇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡靠益,死狀恐怖丧肴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胧后,我是刑警寧澤芋浮,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站壳快,受9級(jí)特大地震影響纸巷,放射性物質(zhì)發(fā)生泄漏江醇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一何暇、第九天 我趴在偏房一處隱蔽的房頂上張望陶夜。 院中可真熱鬧,春花似錦裆站、人聲如沸条辟。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)羽嫡。三九已至,卻和暖如春肩袍,著一層夾襖步出監(jiān)牢的瞬間杭棵,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工氛赐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留魂爪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓艰管,卻偏偏與公主長(zhǎng)得像滓侍,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牲芋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354