TS入門學習筆記

啊就是我發表於2020-01-19

強型別語言與弱型別語言

強型別語言:

 強型別語言不允許改變變數的資料型別,除非進行強制型別轉換。
複製程式碼

弱型別語言:

定義與強型別語言相反,一個變數可以被賦予不同資料型別的值。

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;
}
複製程式碼

相關文章