var和let的區(qū)別

先說區(qū)別

1.使用var聲明的變量,其作用域?yàn)樵撜Z句所在的函數(shù)內(nèi),且存在變量提升現(xiàn)象;
2.使用let聲明的變量,其作用域?yàn)樵撜Z句所在的代碼塊內(nèi),不存在變量提升;
3.let不允許在相同作用域內(nèi),重復(fù)聲明同一個(gè)變量。

1.基本語法

{
  let a = 125;
  var b = 521;
}
a // Uncaught ReferenceError: a is not defined
b // 521

上面代碼中,使用let聲明的變量報(bào)錯(cuò),var聲明的返回正確的值,這說明,let聲明的變量只在它所在的代碼塊有效。

let配合for循環(huán)的應(yīng)用

for (let i = 0; i < 5; i++) {
  console.log(i); //0 1 2 3 4 
}
      
console.log(i); //ReferenceError: i is not defined

上面代碼中,計(jì)數(shù)器i只在for循壞體內(nèi)有效,再循環(huán)體外引用就會(huì)報(bào)錯(cuò)。

下面是常見的面試題目:

for (var i = 0; i <10; i++) {  
    setTimeout(function() {  // 同步注冊(cè)回調(diào)函數(shù)到 異步的 宏任務(wù)隊(duì)列。
         console.log(i);        // 執(zhí)行此代碼時(shí),同步代碼for循環(huán)已經(jīng)執(zhí)行完成
      }, 0);
}
 // 輸出結(jié)果
//10   共10個(gè) 

如果把 var改成 let聲明:

// i雖然在全局作用域聲明,但是在for循環(huán)體局部作用域中使用的時(shí)候,變量會(huì)被固定,不受外界干擾。
for (let i = 0; i < 10; i++) { 
  setTimeout(function() {
    console.log(i);    //  i 是循環(huán)體內(nèi)局部作用域,不受外界影響。
  }, 0);
}
// 輸出結(jié)果:
0  1  2  3  4  5  6  7  8 9

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

for (let i = 0; i < 3; i++) {
  let i = 'love';
  console.log(i);
}
// love
// love
// love

上面代碼正確運(yùn)行,輸出了 3 次abc。這表明函數(shù)內(nèi)部的變量i與循環(huán)變量i不在同一個(gè)作用域,有各自單獨(dú)的作用域。

2.不存在變量提升

var命令會(huì)發(fā)生”變量提升“現(xiàn)象,即變量可以在聲明之前使用,值為undefined。

let命令則不同,它所聲明的變量一定要在聲明后使用,否則報(bào)錯(cuò)。

// var 的情況
console.log(ar); // 輸出undefined
var ar = 512;
    
// let 的情況
console.log(et); // 報(bào)錯(cuò)ReferenceError
let et = 512;

上面代碼變量ar用var聲明,會(huì)發(fā)生變量提升,因沒有值,所以會(huì)輸出undefined。變量et用let聲明的則不會(huì)發(fā)生變量提升。

暫時(shí)性死區(qū)

var tmp=521;
if(true){
    tmp='abc';//ReferenceError: tmp is not defined
    let tmp;
}

上面代碼中,存在全局變量tmp,但是塊級(jí)作用域內(nèi)let又聲明了一個(gè)局部變量tmp,導(dǎo)致后者綁定這個(gè)塊級(jí)作用域,所以在let聲明變量前,對(duì)tmp賦值會(huì)報(bào)錯(cuò)。

ES6 明確規(guī)定,如果區(qū)塊中存在let和const命令,這個(gè)區(qū)塊對(duì)這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會(huì)報(bào)錯(cuò)。(使用const聲明的是常量,在后面出現(xiàn)的代碼中不能再修改該常量的值。)

總之,在代碼塊內(nèi),使用let命令聲明變量之前,該變量都是不可用的。這在語法上,稱為“暫時(shí)性死區(qū)”(temporal dead zone,簡(jiǎn)稱 TDZ)。

不允許重復(fù)聲明

let不允許在相同作用域內(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ò)
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容