TS的變量聲明

  1. 在typescript裏面推薦大家使用let關鍵字來代替大家所熟悉的JavaScript關鍵字varlet關鍵字是JavaScript的一個新概念,TypeScript實現了它

  2. 我們先使用typescirpt的語法將var聲明變量的幾個問題和使用let聲明做一個對比

變量聲明提升 (作用域規則)

function f(flag: boolean):any {
    if (flag) {
        var x:number = 10;
    }
    return x;
}
console.log(f(true));
console.log(f(false));

大家會發現,我們將變量x定義在if語句塊內部,但是卻能在外部訪問它;這就是var的函數作用域;並且flag爲false的時候,也會有打印(undefined),而不是說not defined; 這就是var的變量聲明提升
如果換爲let, x就只能在if塊裏面使用,當flag爲false時,就會顯示x沒有定義,通過看編譯後的源代碼我們也能夠發現ts轉爲js,tsc將變量名直接都改變了,當然就找不到x這個變量的定義了
當用let聲明一個變量,它使用的是詞法作用域或塊作用域;塊作用域變量在包含它們的塊或for循環之外是不能訪問的; 並且沒有聲明提升

多次重複聲明同一個變量不會報錯

var a:number = 1;
var a:number = 2;
console.log(a)  

javascript裏面不會提升我們是否多次聲明瞭同一個變量,遇到這種情況,js會對忽略後續的聲明;但是會執行它的重新賦值操作
如果換位let, 在編譯階段就不會通過;會告訴我們 無法重新聲明塊範圍變量“a”

for循環作用域問題

for (var i:number = 0; i < 5; i++) {
    setTimeout(function f(): void {
        console.log(i);
    }, 1000);
}

最後的結果不是我們希望的 01234,而是5個5,這是因爲我們傳給setTimeout的每一個函數表達式實際上都引用了相同作用域裏(var聲明的變量只有函數作用域和全局作用域,)的同一個i; 在循環結束後,i的值爲5。 所以當函數被調用的時候,它會打印出5個5

我們可以利用IIFE立即自執行函數表達式,創造多個函數作用域出來,爲獲取到的變量創建了一個新的變量環境

for (var i:number = 0; i < 5; i++) {
   (function(i) {
        setTimeout(function(): void {
            console.log(i);
        }, 100 * i);
   })(i);
      }

當let聲明出現在循環體裏時擁有完全不同的行爲。 不僅是在循環裏引入了一個新的變量環境,而是針對 每次迭代都會創建這樣一個新作用域。 這就是我們在使用立即執行的函數表達式時做的事

      for (let i: number = 0; i < 5; i++) {
        setTimeout(function f(): void {
          console.log(i);
        }, 100 * i);
      }

const聲明是聲明變量的另一種方式

與let聲明相似,但是就像它的名字所表達的,它們被賦值後不能再改變。 換句話說,它們擁有與 let相同的作用域規則,但是不能對它們重新賦值

let l1: number = 9;
l1 = 10;
const c2: number = 9;
c2 = 10;

但是對於複雜數據類型有的點特殊

const c2: any = {
    name: 'jack'
};

下面直接改是不行的,因爲相當於給變量b重新開闢了一個內存空間,地址發生了改變,constant類型的值不能更改

c2 = {
   name: 'Lucy'
};

但是下面的代碼是可以正常執行的,因爲改變的是複雜數據類型的值,它們都存儲在堆裏面,只是一個引用,它們的值就是地址還是保存在棧裏面,沒有更改

c2.name = 'Lucy';

選擇 let還是const

  1. 所有變量除了你計劃去修改的都應該使用const。使用 const也可以讓我們更容易的推測數據的流動
  2. 基本原則就是如果一個變量不需要對它寫入,那麼其它使用這些代碼的人也不能夠寫入它們,並且要思考爲什麼會需要對這些變量重新賦值。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章