1. 程式人生 > >es6 let與var的區別詳解

es6 let與var的區別詳解

新特性 筆記 創建 輸出 作用域 習慣 pre ron 設計缺陷

一、前言 說到做到,現在暫時放了放JS模式的讀書筆記,打算好好看看ES6,畢竟出了這麽久了,還是靠JS吃飯的,都不好好學JS新特性,確實說不過去,我本來是想當讀書筆記去記錄ES6,但是這個確實是屬於邊看邊用邊記憶的,所以還是零散的挑重點去記錄吧。 二、let與var的區別 1.let 不能重復申明,var可以 這是最為簡單最容易記憶的一點,當我們使用var申明,是可以反復申明同一個變量的,但並不推薦這個做,因為同名變量的創建對站在內存角度是無意義的,所以let的出現也是為了解決早期JS設計缺陷。
var a = 1;
var a = 2;//不會報錯
let b = 1;
let b 
= 2;//報錯

2.let會產生塊級作用域,且只在自己的作用域內生效,var不受限制

什麽是塊級作用域?當我們在{}中使用了let或者const時,{}的範圍就是一個塊級作用域,此時let只能在{}中使用,外部無法訪問。像這樣:

{
  let a = 1;
  var b = 2;
}
console.log(a);//報錯
console.log(a);//2

或者這樣:

if(true){
  let a = 1;
  var b = 1;
}
console.log(a);
console.log(b);
2.1let與var在for循環中的不同表現
//for循環用var
var a = [];
for (var i = 0; i < 5; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[1]();//5
a[2]();//5
a[3]();//5
//for循環用let
var b = [];
for (let i = 0; i < 5; i++) {
  b[i] = function () {
    console.log(i);
  };
}
b[1]();//1
b[2]();//2
b[3]();//3

在明白上面2個循環的區別之前,我們先來理一理知識點,我們要知道,for循環中設置循環變量的部位其實是一個父作用域,循環體內部是個子作用域。

在父子作用域中同時使用let的情況下,兩個作用域就是互不幹擾的兩個塊級作用域:

{
  let a = 1;
  {
    console.log(a);//報錯
    let a = 2;
    console.log(a);//2
  }
  console.log(a);//1
}

子作用域不使用let,還是可以正常繼承父作用域,父也能讀取子。

{
  let a = 1;
  {
    var b = 2;
    console.log(a);//1
  }
  console.log(a);//1
  console.log(b);//2
}

所以下面這個循環輸出了三次echo,因為在子作用域中申明的i跟父作用域中的i可以說是完全不同的兩個i;

for(let i = 0;i<3;i++){
  let i = ‘echo‘;
  console.log(i);
};//輸出三次echo

但如果你將let改為var,你會發現只輸出一次,因為沒有了塊級作用域,父子作用域共用了一個變量i,第一次循環後,子作用域的i被改為了echo,父作用域中i<3的判斷無法通過,所以只輸出了一次。

那麽回頭再看看最初的兩個循環,為什麽var申明輸出了3個5,而let輸出了1,2,3呢,嘗試去理解,說到底還是塊級作用域搞的鬼。

3.let不存在變量提升 變量提升可以說是var申明設計不嚴謹的一點,可能我們在開發中已經習慣申明一個全局變量,然後可以在申明前後都可以使用它,這很方便,但是不符合規範。
console.log(a);//undefined
var a = 1;
console.log(b);//報錯
let b = 1;
4.let存在暫時性死域 當一個區域存在let申明時,這個區域就形成了一個封閉的作用域,在let申明前使用這個變量就會報錯,也就是只能先申明再使用,這種語法也稱為暫時性死域。
{
  let a = 1;
  {
    console.log(a);//報錯
    let a =2;
  }
}

三、const申明的特點

可以理解為,let的特性const都有,不能反復申明,存在塊級作用域,不存在變量提升,也有暫時性死域的特點。

與let區別在於,const申明的是一個常量,一旦申明就無法修改,let可以,var就更不用說了。

就這樣去記憶吧。

es6 let與var的區別詳解