ES6深入理解之“l(fā)et”能替代”var“嗎?
前言
我已經(jīng)使用ES2015(ES6)的語(yǔ)法編寫JavaScript程序很久了,并且喜歡上它提供的新特性帶來的優(yōu)雅和簡(jiǎn)潔。我最習(xí)慣的就是不再使用var,而是let/const。我想當(dāng)然的以為let僅僅是var的替代者,而事實(shí)上let還為我們提供了更加精細(xì)的作用域。
我大多數(shù)時(shí)候使用的變量都是用const來聲明,因?yàn)槿绻麌L試對(duì)使用const聲明的變量進(jìn)行修改,將會(huì)報(bào)錯(cuò)。這可以避免不小心將一個(gè)不該修改的常量值修改。但是,我們還是需要可以聲明可以被修改的變量,比如在循環(huán)里面的計(jì)數(shù)器,我們需要不斷地對(duì)改變了加1??墒菫槭裁次覀兪褂胠et而不是var呢?
最簡(jiǎn)單的答案就是let提供塊作用域(block-scoping),這會(huì)比var提供的以函數(shù)為作用域有更加精細(xì)化的控制。為了便于理解,我來用一個(gè)經(jīng)典的前端工程師面試的問題來描述兩者的區(qū)別。
問題: 在下面的例子中,請(qǐng)說出控制臺(tái)的打印結(jié)果。
var callbacks = []; (function() { for (var i = 0; i < 5; i++) { callbacks.push( function() { return i; } ); } })(); console.log(callbacks.map( function(cb) { return cb(); } ));
我們將for循環(huán)執(zhí)行五次,每次將一個(gè)函數(shù)push到callbacks數(shù)組中。最后callbacks數(shù)組里面的每一個(gè)函數(shù)的執(zhí)行結(jié)果打印出來。
一個(gè)新手工程師經(jīng)過深思熟慮可能會(huì)回答[0, 1 , 2, 3, 4], 然而卻掉入了JavaScript的”hoisting陷阱”。
只有當(dāng)你理解了hoisting, 才能給出正確的答案[5, 5, 5, 5, 5]。
var callbacks = []; (function() { var i; for (i = 0; i < 5; i++) { callbacks.push( function() { return i; } ); } })(); console.log(callbacks.map( function(cb) { return cb(); } ));
注意:上面的代碼,JavaScript將變量提升到函數(shù)定義的頂部,經(jīng)過整個(gè)for循環(huán),callbacks里面存儲(chǔ)的5個(gè)函數(shù)指向的同一個(gè)變量i的值已經(jīng)是5。所以最終打印出來的值都為5。
在以前要通過各種奇淫技巧來解決這個(gè)問題,并成功返回[0, 1, 2, 3, 4], 現(xiàn)在我們有了let,就可以很簡(jiǎn)單解決問題:
var callbacks = []; (function() { for (let i = 0; i < 5; i++) { callbacks.push( function() { return i; } ); } })(); console.log(callbacks.map( function(cb) { return cb(); } ));
因?yàn)閘et擁有塊作用域,所以使用let聲明的變量i不會(huì)被提升到函數(shù)頂部,i的作用域在for循環(huán), 就會(huì)每次循環(huán)有獨(dú)立的值。
那我們是不是應(yīng)該不要使用var了呢?如果你想要一個(gè)變量擁有函數(shù)作用域,var還是很有用的。
讀者提到的兩個(gè)問題:
1、const聲明的變量不是完全不可更改。比如:
const myNotQuiteImmutableObject = { thisCanBeChanged: "not immutable" }; myNotQuiteImmutableObject.thisCanBeChanged = "see I changed it.";
但是,使用const聲明可以阻止一些基本的更改,比如:
const immutableString = "you can't change me"; immutableString = "D'OH!"; // error
如果你想要完全的不可更改,可以使用Facebook提供的Immutable庫(kù)。
2、老版本的瀏覽器不支持let。不僅如此,而且有些最新的瀏覽器也還沒有支持let。我們可以使用Babel來避免這個(gè)問題,Babel允許你使用所有最新的JavaScript功能,然后將其翻譯到甚至IE8都能支持的代碼。
原文: Why You Shouldn't Use ‘var' Anymore
譯者: Fundebug
為了保證可讀性,本文采用意譯而非直譯。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
簡(jiǎn)述JS中forEach()、map()、every()、some()和filter()的用法
JS中常常需要對(duì)數(shù)組進(jìn)行遍歷、迭代操作,而我們常用的就是for語(yǔ)句對(duì)數(shù)組進(jìn)行迭代,下面這篇文章主要給大家介紹了關(guān)于JS中forEach()、map()、every()、some()和filter()的用法,需要的朋友可以參考下2022-05-05實(shí)例講解DataTables固定表格寬度(設(shè)置橫向滾動(dòng)條)
下面小編就為大家?guī)硪黄獙?shí)例講解DataTables固定表格寬度(設(shè)置橫向滾動(dòng)條)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07asp.net中System.Timers.Timer的使用方法
asp.net中System.Timers.Timer的使用方法,需要的朋友可以參考一下2013-03-03JavaScript實(shí)現(xiàn)簡(jiǎn)易QQ聊天界面
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)簡(jiǎn)易QQ聊天界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07基于javascript顯示當(dāng)前時(shí)間以及倒計(jì)時(shí)功能
這篇文章主要為大家詳細(xì)介紹了基于javascript顯示當(dāng)前時(shí)間以及倒計(jì)時(shí)功能的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03