第一 : 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滤愕,因?yàn)樗衖都引用相同的函數(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é)果众羡,因?yàn)閮?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、實(shí)際上const變量的內(nèi)部狀態(tài)是可修改的球昨。 幸運(yùn)的是尔店,TypeScript允許你將對象的成員設(shè)置成只讀的。
注意: let vs const
最小特權(quán)原則:所有變量除了你計劃去修改的都應(yīng)該使用const