關(guān)于ES6的let命令

1盲憎、let的基本用法以及l(fā)et和var的區(qū)別

(1) let與var一樣是用來聲明變量的,與var的區(qū)別是let所聲明的變量胳挎,只在let所在的代碼塊內(nèi)有效

eg1:
{
  let a = 10;
  var b = 1;
}
eg2:
for(let i=0;i<5;i++){
console.log(i);//輸出1,2,3,4
}
console.log(i);//i is not defined

可以看上面這段代碼饼疙,也就是說let聲明的變量只能在{ }里面獲取,在{}外面是獲取不到慕爬,但是var聲明的變量在{}內(nèi)外都能獲取到

(2) let未先聲明變量就用變量會編譯出錯窑眯,但是var不會,會輸出undefined
另外let不允許在同一作用域下聲明已經(jīng)存在的變量澡罚,即在同一作用域下不可以聲明兩個變量名相同的變量伸但,會直接報錯肾请,但是var不會留搔,可見let比var更加規(guī)范化

console.log(a);//報錯:a is not defined
let a=1;

console.log(a);//undefined
var a=1;
}

(3) let在for循環(huán)內(nèi)作用域問題1

{
for (let i = 0 /* 作用域a */; i < 3; console.log("in for expression", i), i++) {
    let i; //這里沒有報錯,就意味著這里跟作用域與上面a的作用域不同
    console.log("in for block", i);
}

(4) let在for循環(huán)內(nèi)作用域問題2
1)關(guān)于下面eg1這段代碼為什么輸出結(jié)果是10呢铛铁?因?yàn)閒or里面的i的作用域是整個外部區(qū)域隔显,所以,當(dāng)調(diào)用a6的時候饵逐,其實(shí)運(yùn)行的是console.log(i)括眠,而此時因?yàn)榕芡暄h(huán),i的值是10倍权,所以輸出10

2)關(guān)于eg2輸出結(jié)果是6掷豺,因?yàn)樵贓S標(biāo)準(zhǔn)中捞烟,有一段是關(guān)于CreatePerIterationEnvironment,也就是for語句每次循環(huán)所要建立環(huán)境的步驟当船,里面有提及有關(guān)詞法環(huán)境的相關(guān)步驟(LexicalEnvironment)题画,這與使用let時會有關(guān)。所以德频,如果你使用了let而不是var苍息,let的變量除了作用域是在for區(qū)塊中,而且會為每次循環(huán)執(zhí)行建立新的詞法環(huán)境(LexicalEnvironment)壹置,拷貝所有的變量名稱與值到下個循環(huán)執(zhí)行竞思。

eg1使用var:
var a = [];
for (var i = 0; i < 10; i++) {
  // 作用域a
  a[i] = function () {
    // 作用域b
    console.log(i);
  };
}
a[6](); // 10


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

eg2:里面的代碼其實(shí)就相當(dāng)于下面這段代碼

var a = [];
{ let k;
    for (k = 0; k < 10; k++) {
      let i = k; //注意這里,每次循環(huán)都會創(chuàng)建一個新的i變量
      a[i] = function () {
        console.log(i);
      };
    }
}
a[6](); // 6

(5) let的暫時性死區(qū):只要塊級作用域內(nèi)存在let命令钞护,它所聲明的變量就“綁定”(binding)這個區(qū)域盖喷,不再受外部的影響,
死區(qū)范圍:在let命令聲明變量tmp之前难咕,都屬于變量tmp的“死區(qū)”传蹈。
下面這段代碼中,聲明了一個全局對象tmp步藕,并在if語句體對tmp進(jìn)行重新賦值惦界。正常來說,該語句是正確的咙冗,但是添加了“l(fā)et tmp”后沾歪,運(yùn)行該程序,就會報錯雾消,顯示“ReferenceError”灾搏。大多數(shù)人往往會忽略到第一個聲明的tmp變量作用域包裹了第二個tmp

例1:
var tmp = 123;
if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

例2:
function bar(x = y, y = 2) {//y還沒有定義的時候就使用y
  return [x, y];
}

bar(); // 報錯

例3:
// 不報錯
var x = x;
// 報錯
let x = x;

(6)塊級作用域
ES6以前變量的作用域是函數(shù)范圍,有時在函數(shù)內(nèi)局部需要一些臨時變量立润,因?yàn)闆]有塊級作用域狂窑,所以就會將局部代碼封裝到IIEF中,這樣達(dá)到了想要的效果又不引入多余的臨時變量桑腮。而塊作用域引入后泉哈,IIEF當(dāng)然就不必要了!

function f(){
   ...
   swap(var_a,var_b);
   (function swap(a,b){
       var tmp;
       tmp = a;
       a = b;
       b=tmp;
   })(var_a,var_b);
}

如上面的代碼破讨,tmp被封裝在IIFE中丛晦,就不會污染上層函數(shù);而有塊級作用域提陶,就不用封裝成IIEF烫沙,直接放到一個塊級中就好。

{
// 塊級作用域?qū)懛?{
  let tmp = ...;
  ...
}
}

(7)ES6對函數(shù)的改革

{
function add(x,y){return x+y};//這是es5中定義函數(shù)的寫法

var add=(x,y)=>x+y;//es6中我們可以這么搞:
add(1,2);//3,正常運(yùn)行

var fun1=x=>x+1;
fun1(3);//4,當(dāng)參數(shù)為1個的時候 可以再簡單一點(diǎn)隙笆,當(dāng)然復(fù)雜函數(shù)還是需要括號與大括號的

var fun2=(...args)=>{
  for(let arg of args){
      console.log(arg)
  }
};
fun2(1,2,3);//1,2,3配合rest參數(shù)锌蓄,fun2()里面的實(shí)參1,2,3會傳到args被當(dāng)做args的值升筏,...args是es6的擴(kuò)展運(yùn)算符,會把參數(shù)fun2()傳遞的實(shí)參作為一個數(shù)組
}

上面我們提到了擴(kuò)展運(yùn)算符瘸爽,es6擴(kuò)展運(yùn)算符仰冠,也就是... ,作用是將一個數(shù)組轉(zhuǎn)為用逗號分隔的參數(shù)序列蝶糯。
那么問題就來了洋只,我們?yōu)樯兑眠@么奇怪的東東涅,當(dāng)然因?yàn)樗艽蟠筇岣呶覀兊拈_發(fā)效率昼捍。因此识虚,我們可別小看這三個點(diǎn)。下面我們來總結(jié)兩條這三個小點(diǎn)的用途:
(1)復(fù)制數(shù)組:
在es5時代妒茬,要想復(fù)制數(shù)組担锤,最容易想到的是通過for循環(huán)一個一個push,或者來個slice()的乍钻,現(xiàn)在有了擴(kuò)展運(yùn)算符肛循,直接一步就能搞定:

var  arr = [1,2,3,4,5];
var copy = [...arr];

(2)將類似數(shù)組的對象轉(zhuǎn)換為真正的數(shù)組
任何類似數(shù)組的對象可以用擴(kuò)展運(yùn)算符轉(zhuǎn)換為真正的數(shù)組。比如:

var newNode= document.querySelectorAll('div');
var array = [...newNode];
Array.isArray(array)   //true
var str = 'hello';
var aStr = [...str];
Array.isArray(aStr)    //true

(8)關(guān)于es6函數(shù)聲明的行為方式:
1允許在塊級作用域內(nèi)聲明函數(shù)。
2函數(shù)聲明類似于var,即會提升到全局作用域或函數(shù)作用域的頭部伏伯。
3同時,函數(shù)聲明還會提升到所在的塊級作用域的頭部夹孔。

上面的三條規(guī)則只對 ES6 的瀏覽器實(shí)現(xiàn)有效,其他環(huán)境的實(shí)現(xiàn)不用遵守析孽,還是將塊級作用域的函數(shù)聲明當(dāng)作let處理搭伤。

根據(jù)這三條規(guī)則,在瀏覽器的 ES6 環(huán)境中袜瞬,塊級作用域內(nèi)聲明的函數(shù)怜俐,行為類似于var聲明的變量。

考慮到環(huán)境導(dǎo)致的行為差異太大邓尤,應(yīng)該避免在塊級作用域內(nèi)聲明函數(shù)拍鲤。如果確實(shí)需要,也應(yīng)該寫成函數(shù)表達(dá)式裁赠,而不是函數(shù)聲明語句殿漠。如下

// 函數(shù)聲明語句
{
  let a = 'secret';
  function f() {
    return a;
  }
}

// 函數(shù)表達(dá)式
{
  let a = 'secret';
  let f = function () {
    return a;
  };
}

另外,還有一個需要注意的地方佩捞。ES6 的塊級作用域允許聲明函數(shù)的規(guī)則,只在使用大括號的情況下成立蕾哟,如果沒有使用大括號一忱,就會報錯莲蜘。

// 不報錯
'use strict';
if (true) {
  function f() {}
}

// 報錯
'use strict';
if (true)
  function f() {}

總結(jié):

1、通過var定義的變量帘营,作用域是整個封閉函數(shù)票渠,是全域的 。通過let定義的變量芬迄,作用域是在塊級或是子塊中问顷。

2、使用 let 聲明的變量禀梳,在聲明前無法使用杜窄,否則將會導(dǎo)致錯誤,并且不允許重復(fù)聲明算途。

3塞耕、如果未在 let 語句中初始化您的變量,則將自動為其分配 JavaScript 值 undefined嘴瓤。

4扫外、變量提升:不論var聲明的變量處于當(dāng)前作用域的第幾行,都會提升到作用域的頭部廓脆。
-var 聲明的變量會被提升到作用域的頂部并初始化為undefined筛谚,而let聲明的變量在作用域的頂部未被初始化

5、暫時性死區(qū)停忿,在代碼塊內(nèi)使用let命令聲明變量之前刻获,該變量都是不可用的,不受外部變量影響瞎嬉;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蝎毡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子氧枣,更是在濱河造成了極大的恐慌沐兵,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件便监,死亡現(xiàn)場離奇詭異扎谎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)烧董,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門毁靶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人逊移,你說我怎么就攤上這事预吆。” “怎么了胳泉?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵拐叉,是天一觀的道長岩遗。 經(jīng)常有香客問我,道長凤瘦,這世上最難降的妖魔是什么宿礁? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蔬芥,結(jié)果婚禮上梆靖,老公的妹妹穿的比我還像新娘。我一直安慰自己笔诵,他們只是感情好返吻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嗤放,像睡著了一般思喊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上次酌,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天恨课,我揣著相機(jī)與錄音,去河邊找鬼岳服。 笑死剂公,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吊宋。 我是一名探鬼主播纲辽,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼璃搜!你這毒婦竟也來了拖吼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤这吻,失蹤者是張志新(化名)和其女友劉穎吊档,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體唾糯,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怠硼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了移怯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片香璃。...
    茶點(diǎn)故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖舟误,靈堂內(nèi)的尸體忽然破棺而出葡秒,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布同云,位于F島的核電站糖权,受9級特大地震影響堵腹,放射性物質(zhì)發(fā)生泄漏炸站。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一疚顷、第九天 我趴在偏房一處隱蔽的房頂上張望旱易。 院中可真熱鬧,春花似錦腿堤、人聲如沸阀坏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忌堂。三九已至,卻和暖如春酗洒,著一層夾襖步出監(jiān)牢的瞬間士修,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工樱衷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棋嘲,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓矩桂,卻偏偏與公主長得像沸移,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子侄榴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 格格君的小隨筆 ——淺談讀書與智慧 如果你遇到一個具有才華的人雹锣,應(yīng)當(dāng)問他讀的是什么書。要學(xué)會在書中去找尋智...
    別具一格格閱讀 185評論 0 1
  • 今日早餐:紅薯葉雞蛋餅癞蚕,蔥油餅蕊爵,原味豆?jié){
    魅力度閱讀 315評論 3 1
  • 20180122 【幸福三朵玫瑰 昨日三朵玫瑰已采 今日三朵玫瑰 1.上班 2.給大寶肯定,給小寶按摩 3.尊重并...
    徐則蘭閱讀 160評論 0 2
  • 今早起床涣达,為了今晚的微課在辆,備了一早的課,今晚發(fā)現(xiàn)度苔,其實(shí)匆篓,作為微課的講師不難,而且越分享越快樂寇窑。一件超出6月生命之花...
    女巫的夢想閱讀 287評論 0 0
  • 關(guān)注正向與堅(jiān)持規(guī)則并行: 今晚帶孩子上街買東西鸦概,孩子挑了一個自己很喜歡的書皮,結(jié)賬的時候,收銀員說書皮要買就買...
    尤占芳閱讀 206評論 0 0