TS基礎(chǔ)篇3:變量

第一 : var

1、var聲明有些奇怪的作用域規(guī)則:
-----var聲明可以在包含它的函數(shù),模塊,命名空間或全局作用域內(nèi)部任何位置被訪問

function f(shouldInitialize: boolean) {
    if (shouldInitialize) {
        var x = 10;
    }
    return x;
}
f(true);    // return '10'
f(false);   // return 'undefined'

可能引發(fā)的錯誤:多次聲明同一個變量并不會報錯,可能在代碼審查時漏掉,引發(fā)無窮的麻煩

function sumMatrix(matrix: number[][]) {
    var sum = 0;
    for (var i = 0; i < matrix.length; i++) {
        var currentRow = matrix[i];
        for (var i = 0; i < currentRow.length; i++) {
            sum += currentRow[i];
        }
    }

    return sum;
}

問題:里層的for循環(huán)會覆蓋變量i,因為所有i都引用相同的函數(shù)作用域內(nèi)的變量
------這個版本的循環(huán)不能得到正確的結(jié)果


2、捕獲變量的怪異之處

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

輸出:
10 10 10 10 10 10 10 10 10 10 10 

原因:setTimeout在若干毫秒后執(zhí)行一個函數(shù),并且是在for循環(huán)結(jié)束后。 for循環(huán)結(jié)束后,i的值為10。 所以當(dāng)函數(shù)被調(diào)用的時候,它會打印出 10!

解決辦法:
使用立即執(zhí)行的函數(shù)表達(dá)式(IIFE)來捕獲每次迭代時i的值

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

第二:let

let聲明使用的是詞法作用域或塊作用域
1、變量在包含它們的塊或for循環(huán)之外是不能訪問的

function f(input: boolean) {
    if (input) {
        let b =  1;
        return b;
    }
    // Error: 'b' doesn't exist here
    return b;
}

2、變量不能在被聲明之前讀或?qū)憽?br> ---- 雖然這些變量始終“存在”于它們的作用域里,但在直到聲明它的代碼之前的區(qū)域都屬于 暫時性死區(qū)

function foo() {
    return a;
}
// 不能在'a'被聲明前調(diào)用'foo'
foo();
let a;

3、變量不能重定義
@var定義的變量是可以重定義,但之后得到最后一個

let x = 10;
let x = 20; // 錯誤,不能在1個作用域里多次聲明`x`

4、變量屏蔽
屏蔽:在一個嵌套作用域里引入一個新名字的行為

function sumMatrix(matrix: number[][]) {
    let sum = 0;
    for (let i = 0; i < matrix.length; i++) {
        var currentRow = matrix[i];
        for (let i = 0; i < currentRow.length; i++) {
            sum += currentRow[i];
        }
    }

    return sum;
}

這個版本的循環(huán)能得到正確的結(jié)果,因為內(nèi)層循環(huán)的i可以屏蔽掉外層循環(huán)的i。


5、let聲明出現(xiàn)在循環(huán)體里時擁有完全不同的行為
原理:不僅是在循環(huán)里引入了一個新的變量環(huán)境,而是針對 每次迭代都會創(chuàng)建這樣一個新作用域。** 這就是我們在使用立即執(zhí)行的函數(shù)表達(dá)式時做的事**

for (let i = 0; i < 10 ; i++) {
    setTimeout(function() {console.log(i); }, 100 * i);
}
輸出: 0 1 2 3 4 5 6 7 8 9

第三 : const

1、與let聲明相似,但被賦值后不能再改(常量)
2、實際上const變量的內(nèi)部狀態(tài)是可修改的。 幸運的是,TypeScript允許你將對象的成員設(shè)置成只讀的。


注意: let vs const

最小特權(quán)原則:所有變量除了你計劃去修改的都應(yīng)該使用const

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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