ts 宣告變數有var
、let
和const
三種方式,它們在 ts 中的用法與 js 一致。
與其他語言的變數宣告相比,var
宣告的變數有一些比較奇怪的作用域規則,主要體現在:
最常見的例子如下:
function f1() , 100 * i)
}}f1();
很多人認為輸出列印為 0 到 10 的數字,然而真實列印為 10 個 10。這就是函式作用域在作怪。上面**只有等到for
迴圈結束後才會列印輸出,f2
中的i
指向是f1
函式作用域中的i
,等到f2
執行時i
已經是 10 。
要想輸出 0 到 10 也很簡單。既然只有作用域才能捕獲變數,那麼我們可以在f1
和f2
之間再加一層函式作用域。
function f1() , 100 * i)
})(i);
}}f1();
形如fn
函式的用法稱為立即執行函式表示式(iife,immediately invoked function expression),它會在每次迴圈中都執行一次,並把當時的i
值作為引數被fn
的函式作用域捕獲。這樣,執行f2
時就會先查找到fn
函式作用域中的i
值。
要實現相同的效果,還有更簡單的辦法,那就是使用接下來要說的let
。
為了避免var
的各項怪異行為,es 6 引入了let
,它的語法與var
相同,但是卻有更加嚴謹的使用方式。主要表現為引入塊級作用域,也稱為詞法作用域。
塊級作用域的引入意味著不再需要使用建立函式來定義乙個新的作用域,而只需要使用大括號{}
即可以建立乙個新的作用域。
塊級作用域中的變數必須先宣告後使用,相同作用域內不允許重複宣告。
作為作用域,函式作用域和塊級作用域是相同的,具有以下特點:
尋找變數時逐層外外查詢,直到找到為止,否則報引用錯誤
內層作用域可以訪問外層作用域內的變數,而反過來不行
內層作用域變數會遮蔽(shadowing)外層作用域中的同名變數(特點 1 的推論)
作用域內**即使已經執行完畢,該作用域捕獲的變數仍然存在(閉包)
針對特點 4 舉例:
function thecitythatalwayssleeps()
}return getcity();
}
上例中,執行getcity()
時,if
**塊已經執行完畢,但是我們仍然可以使用city
,因為fn
函式作用域捕獲了if
塊作用域內的city
。
當let
宣告作為迴圈語句的一部分時,它有特殊表現:它為每次迴圈建立乙個新的塊級作用域,而不是為整個迴圈語句本身建立乙個作用域。所以,上文中迴圈設定settimeout
的問題可以使用以下方式輕鬆解決,因為每次迭代時,f2
和f1
之間都會建立乙個新的塊級作用域。
function f1() , 100 * i)
}}f1();
const
與let
一致,唯一不同的是,它宣告的變數只能在宣告時賦值,之後都不能被再次賦值,對應其他語言中所說的常量。
對於使用const
宣告的陣列和物件,宣告的變數本身是不能被修改的,但是陣列元素和物件屬性仍然是可以被修改。
解構把資料從陣列或者物件中提取出來並賦值給對應變數。
let [first, second] = [1, 2];
// => first = 1, second = 2
[second, first] = [first, second];
// swap => first = 2, second = 1
let [alpha, ...rest] = [1, 2, 3];
// => alpha = 1, rest = [2, 3]
解構同名屬性。
let o = ;
let = o;
// => a = 1, b = 2
let = o;
// => a = 1, other =
let = o;
// rename => first = 1, second = 2
let = o;
// default => d = 4
function f() {}
f(o);
// => a = 1, b = 2
拓展運算子與解構相反,它把資料展開並合併到陣列或者物件中,使用...
語法。
let first = [1, 2];
let second = [3, 4];
let both = [...first, ...second];
// => both = [1, 2, 3, 4]
let o1 = ;
let o2 = ;
// => o2 =
題外話:如果使用了 es6 語法,但是又不想新增object.asign
的 polyfill ,此時可以使用拓展運算子實現相同的效果而不需 polyfill 。
注意:
class c
}let c = new c();
let clone = ;
clone.p; // ok
clone.m(); // error! 物件例項方法能展開
Typescript 常用變數型別宣告
基礎型別 number boolean string const int arg1 number 陣列型別 const arr1 arg1 number 另一種寫法,使用泛型 const arr2 arg1 array 任意型別 any any 表示引數可以為任意型別 const any arg1 ...
typeScript 入門 資料的變數宣告
typescript學習模板 基本資料型別 數字 let num0 預設any 泛型 let num1 0let num2 number let num3 number 123 字串 let str0 預設any 泛型 let str1 str1 let str2 string let str3 s...
TypeScript高階篇 宣告合併
如果定義了兩個相同名字的函式 介面或類,那麼他們會合併成乙個型別 函式的合併 我們可以使用過載定義多個函式型別 function reverse x number number function reverse x string string function reverse x number st...