強型別語言與弱型別語言
強型別語言:
強型別語言不允許改變變數的資料型別,除非進行強制型別轉換。
複製程式碼
弱型別語言:
定義與強型別語言相反,一個變數可以被賦予不同資料型別的值。
var a = 'a';
var b = 111;
a = b;
console.log(a) // 111
複製程式碼
動態型別語言與靜態型別語
動態型別語言: 在執行階段才做型別檢查。
例如:js/python等就是屬於動態型別語言,對型別檢查非常寬鬆
複製程式碼
靜態型別語言: 在編譯階段就做型別檢查
例如: c++/Java等屬於靜態型別語言,對型別檢查非常嚴格,bug在編譯階段就會被發現。
複製程式碼
基礎型別
ES6的型別可以分為Boolean,Number,String,Array,Function,Object,Symbol,undefined,null。
TypeScript的資料型別則在ES6的基礎上加上void,any,never,元組,列舉,高階型別。
複製程式碼
基礎語法:
: type
TypeScript的基本型別語法是在變數之後使用冒號進行型別標識
這種語法也揭示了TypeScript的型別宣告實際上是可選的。
複製程式碼
1、number型別
let num: number = 123
複製程式碼
2、boolean
boolean是最基礎的資料型別,在ts中,使用boolean來定義布林值
let isCheck: boolean = false;
複製程式碼
3、string
在ts中,使用string來定義字串型別
let name: string = 'Mi FE'
複製程式碼
4、undefined和null
在TypeScript裡,undefined和null兩者各自有自己的型別分別叫做undefined和null。
和 void相似,它們的本身的型別用處不是很大:
複製程式碼
undefined型別的資料只能被賦值為undefined
在typescript中,已宣告未經過初始化的值要直接訪問的話,型別需要定義為undefind
null型別只能被 被賦值為null
null為一個空指標物件,undefined是一個未初始化的變數。所以,可以把undefined看成一個空變數,把null看成一個空物件。
特別注意:預設情況,undefined和null型別,是所有其他型別的子型別,所以也就是說,它兩可以給所有其他型別賦值。
let _undefined: undefined = undefined;
let _null: null = null;
複製程式碼
5、array
在ts中,定義陣列方式有兩種: 可以在元素型別後面接上[],表示由此元素組成的一個陣列:
let arr1: number[] = [1, 2, 3]
複製程式碼
使用陣列泛型,Array<元素型別> :
let arr2: Array<number> = [1, 2, 3]
複製程式碼
建構函式
let arr3: string[] = new Array(‘a’, ‘b’)
複製程式碼
聯合型別:這裡的聯合型別是指,陣列中的元素型別可以是,聯合型別包含的型別。
let arr4: Array<number | string> = [0, ‘1’]
複製程式碼
6、元組
元組型別允許表示一個已知元素數量和型別的陣列,各元素的型別不必相同。 比如,你可以定義一對值分別為number和string型別的元組。
let hello: [number, string] = [0, 'hello']
複製程式碼
元組和陣列看起來有點類似,但是區別在於元組的長度是有限的,而且分別為每一個元素定義了型別
7、列舉
enum型別是對JavaScript標準資料型別的一個補充。 像C#等其它語言一樣,使用列舉型別可以為一組數值賦予友好的名字。
// nan = 1 數字列舉下標是從0開始的,可以自行設定列舉成員的初始值,他們會依次增加。
enum NUM {
F,
S,
T
}
console.log(NUM.F) //0
console.log(NUM.S) //1
console.log(NUM.T)// 2
複製程式碼
8、void
表示沒有任何返回值,一般用於定義方法是方法沒有返回值
function f1() : void {
console.log(‘函式無返回值,為void型別’)
}
複製程式碼
9、any
其他型別都是any型別的子型別,any型別的值可以被賦值為任何型別的值
let something: any = 42;
something.mayExist() //沒問題,因為可能在執行時存在該方法
something.toFixed() //沒問題,方法確實存在,編譯器不會去檢查
複製程式碼
10、never
如果一個函式永遠沒有返回值時,我們可以宣告其為void型別:
function fn(): never {
throw new Error('never');
}
複製程式碼
11、日期型別
let da: Date = new Date()
複製程式碼
12、正規表示式型別
//建構函式神宣告法
let rg1 : RegExp = new RegExp(‘hyx’, gi)
//字面量的宣告法
let rg2: RegExp = /hyx/gi
複製程式碼
函式
函式定義:定義函式有函式宣告和函式表示式兩種形式,定義函式的引數和返回值可以指定其型別;當呼叫函式時,傳入引數型別必須與定義函式引數型別保持一致。
1、函式宣告定義:
//輸入型別 輸出型別
function fn(age:number) : string{
return ‘今年 ${age} 歲’;
}
複製程式碼
2、函式表示式定義
// a
let f1 = (age:number):string => {
return ‘今年 ${age } 歲’
}
let age : number = 22;
let res : string = f(age);
console.log(res);//今年22歲
複製程式碼
⚠️注意:表示式定義完以後,必須呼叫函式
函式表示式還存在另一種寫法: 函式表示式:指定變數fn的型別。
複製程式碼
1、函式沒有返回值可以使用void型別指定返回值
// b
function f3(): viod {
console.log(‘沒有返回值’);
}
f3()
複製程式碼
2、可選引數的函式
注意⚠️:可選引數一定要放在引數的最後面。
// c
function f4(age: number, cm?:number) :string {
//cm 為可選引數,可傳可不傳
}
複製程式碼
3、剩餘引數的函式
當有很多引數的時候,或者函式的個數不確定,可以使用三點運算子。
// d
function fn (…rest: number[] : number[] ) {
return […rest]
}
console.log(fn(1, 3, 5, 7, 9))
function fn2(a:number, b:number, …rest: number[]): number[] {
return [a, b, …rest ];
}
console.log(fn2(10, 22, 1, 3, 5, 7, 9))
複製程式碼
4、函式的過載
先宣告所有方法過載的定義,不包含方法方法的實現,再宣告一個引數為any型別的過載方法,實現any型別1的方法並通過引數型別(和返回型別)不同,來實現過載。
Typescript中的過載:通過為同一函式提供多個函式定義來實現多種功能的目的,Typescript會優先從最前面的函式定義開始匹配,所以多個函式如果有包含關係,需要優先把精確的定義寫在前面。
function f1(x: number, y: number) :number;
function f1(x: string, y: string): string;
//上面定義函式的格式,下面定義函式的具體實現
function f1 (x:any, y:any): any {
return x+y;
}
f1(1, 2);
f1(‘a’, ‘b’);
複製程式碼
類
1、Ts多型
在父親類定義方法但是不去實現,讓繼承他的子類來實現該方法,這樣就使得每一個子類都會改方法有了不同的表現形式。
複製程式碼
2、類和介面
類可以實現介面,通過介面,你可以強制地指明類遵守的某個契約。你可以在介面中宣告一個方法,然後要求類去具體實現它。
介面不可以被例項化,實現介面必須重寫介面中的抽象方法。
複製程式碼
3、類和介面的區別
a、類可以實現多個介面,但只能擴充套件自一個抽象類。
b、抽象類中可以包含具體實現,但是介面不可以。
c、抽象類在執行中是可見的,可以通過instanceof判斷。介面則直線編譯時起作用。
d、介面只能描述類的公共部分,不會檢查私有成員,而抽象沒有這樣的限制。
複製程式碼
4、抽象類和抽象方法
a、用abstract關鍵字定義抽象類和抽象方法,抽象類中的抽象方法不包括具體實現並且必須在派生類中實現。
b、抽象類:它是提供其他類繼承的基礎類,不能直接被例項化,子類繼承可以被例項化。
abstract修飾的方法(抽象方法),只能放在抽象類中
c、抽象類和抽象方法用來定義標準版(比如定義標準為:抽象類中有抽象方法,要求他的子類必須也要有這個方法)
複製程式碼
5、介面:
a、介面定義:介面是對傳入引數進行約束,或者對類裡面的屬性和方法進行宣告和約束,實現這個介面的類必須實現該介面裡面的屬性和方法;typeScript的介面用interface關鍵字來定義。
b、介面作用:介面定義了某一批類所需要遵守的規範,介面不關心這些類的內部狀態資料。也不關心這些類裡方法的實現細節,它只規定這批類裡面必須提供某些方法1,提供這些方法的的類就可以滿足實際需要。ytpescript介面類似於java,同是還增加了更靈活的介面型別,包括屬性,函式,可索引和類等。
c、屬性介面:對傳入物件的約束,也就是Json資料。
d、函式型別的介面:對方法傳入的引數和返回值進行約束。
e、可索引的介面:對索引傳入的引數的約束。
f、類和型別介面:對類的約束。對類的屬性和方法進行約束,類實現介面要用implements,子類必須實現介面裡面宣告的屬性和方法。
g、介面繼承:如果父介面中有定義的但沒有實現的方法,實現子介面時,必須也要實現繼承於父類介面中的方法。
複製程式碼
泛型
定義:不預先確定的資料型別,具體的型別需要在使用的時候才能確定
例子: 宣告一個列印函式,實現把傳入的字串列印出來:
function log(value: string): string {
console.log(value)
return value
}
複製程式碼
加一個需求,要實現能把字串陣列也列印出來:
function log(value: string): string
function log(value: string[]): string[]
function log(value: any): {
console.log(value)
return value
}
複製程式碼
如上所示,可以用之前的函式過載來實現。
再加一個需求,要實現能把任何型別的引數列印出來。泛型就派上用場了:
function log<T>(value: T): T {
console.log(value);
return value;
}
複製程式碼