使用VS Code開發TypeScript--定義變量推薦使用let
目錄
作用域規則
一直以來我們都是通過var關鍵字定義JavaScript變量。
var a = 10;
大家都能理解,這里定義了一個名為a值為10的變量。
我們也可以在函數內部定義變量:
function f() {
var message = "Hello, world!";
return message;
}
並且我們也可以在其它函數內部訪問相同的變量。
function f() {
var a = 10;
return function g() {
var b = a + 1;
return b;
}
}
var g = f();
g(); // returns 11;
上面的例子里,g可以獲取到f函數里定義的a變量。 每當g被調用時,它都可以訪問到f里的a變量。 即使當g在f已經執行完后才被調用,它仍然可以訪問及修改a。
對於熟悉其它語言的人來說,var聲明有些奇怪的作用域規則。 看下面的例子:
function f(shouldInitialize: boolean) {
if (shouldInitialize) {
var x = 10;
}
return x;
}
f(true); // returns '10'
f(false); // returns 'undefined'
有些讀者可能要多看幾遍這個例子。 變量x是定義在if語句里面,但是我們卻可以在語句的外面訪問它。 這是因為var聲明可以在包含它的函數,模塊,命名空間或全局作用域內部任何位置被訪問,包含它的代碼塊對此沒有什么影響。 有些人稱此為var作用域或函數作用域。 函數參數也使用函數作用域。
這些作用域規則可能會引發一些錯誤。 其中之一就是,多次聲明同一個變量並不會報錯:
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循環會覆蓋變量i,因為所有i都引用相同的函數作用域內的變量。 有經驗的開發者們很清楚,這些問題可能在代碼審查時漏掉,引發無窮的麻煩。
JavaScript的嚴格模式
除了正常運行模式,ECMAscript 5添加了第二種運行模式:"嚴格模式"(strict mode)。顧名思義,這種模式使得Javascript在更嚴格的條件下運行。
"嚴格模式"體現了Javascript更合理、更安全、更嚴謹的發展方向,包括IE 10在內的主流瀏覽器,都已經支持它,許多大項目已經開始全面擁抱它。
另一方面,同樣的代碼,在"嚴格模式"中,可能會有不一樣的運行結果;一些在"正常模式"下可以運行的語句,在"嚴格模式"下將不能運行。掌握這些內容,有助於更細致深入地理解Javascript,讓你變成一個更好的程序員。
進入"嚴格模式"的標志,是下面這行語句:
"use strict";
老版本的瀏覽器會把它當作一行普通字符串,加以忽略。
在TypeScript中,let、const語句需要嚴格模式,因此,在TypeScript(ts)文件的第一行應該是:
"use strict";
或者把文件tsconfig.json的"target"改為:
"target": "es5"
這樣才能保證使用let語句正確。否者,出現:"Block-scoped declarations (let, const, function, class) not yet supported outside strict mode" 錯誤。
let與var的區別
在TypeScript中,定義變量要用關鍵字var或者let。let是一種新的var,let和var的區別就是let使js實現了它的塊級作用域,即詞法作用域或塊作用域(注:let可以看成var,它定義的變量被限制在特定范圍中才能使用,離開這個范圍就自動銷毀)。
for (var i = 0; i < 10; i++) {
setTimeout(function() { console.log(i); }, 100 * i);
}
上面代碼執行結果:
10
10
10
10
10
10
10
10
10
10
改為let之后:
for (let i = 0; i < 10 ; i++) {
setTimeout(function() {console.log(i); }, 100 * i);
}
執行結果:
0
1
2
3
4
5
6
7
8
9
這才是我們希望的結果,因此我們推薦在TypeScript中定義變量盡量使用let。
