TS学习总结
(1)編譯開發TS可以使用
(2)數據類型
數據類型主要作用是:方便數據維護和數據校驗;
布爾類型 boolean 數字類型 number 字符串類型 string 數組類型 array 元組類型 tuple 枚舉類型 enum 任意類型 any null 和 undefined void類型 never類型數組的三種寫法:
var arr:number[] = [11,22,33]; console.log(arr); var arr:Arrary<number> =[11,22,33]; console.log(arr); var arr:any[] =['1yhuyhub1',22,33,true]; console.log(arr);元祖類型
枚舉類型
沒有類型如果沒有賦值,則打印的就是下標;
任意類型
任意類型可以解決很多問題,比如處理元素節點;
如上圖,如果使用Object類型會報錯,使用any類型就不會報錯了~
null 和 undefined
null 和 undefined是其他類型(never)的子類型;
正確的使用方法
如果沒有值的話,可以同時定義一個當前類型和其他的null或者undefined類型
如上圖,定義未賦值 或者 定義賦值都不會報錯;
void類型
void表示沒有任何類型,一般用于定義方法的時候沒有返回值
有返回值的話,要指定返回值類型
never類型
never類型表示的是那些永不存在的值的類型。 例如, never類型是那些總是會拋出異?;蚋揪筒粫蟹祷刂档暮瘮当磉_式或箭頭函數表達式的返回值類型; 變量也可能是 never類型,當它們被永不為真的類型保護所約束時。
never類型是任何類型的子類型,也可以賦值給任何類型;然而,沒有類型是never的子類型或可以賦值給never類型(除了never本身之外)。 即使 any也不可以賦值給never。
var a:never; a=(()=>{throw new Error('錯誤'); })()(3)ts函數
原始ES5寫法
TS 寫法:聲明 和 匿名函數兩種
函數聲明
function run():string{return 'ni shi haoren' }匿名函數
var fun2 = function():string{return 'ni shi haoren' }定義傳參
function run(name:string,age:number):string{return `${name}---${age}` } run('zhangsan',34);//-----或者-------var func2 = function(name:string,age:number):string{return `${name}---${age}` } run2('zhangsan',34);// -------沒有返回值的函數-----function run(name:string,age:number):void{console.log(`${name}---${age}`) }TS中的形參
- 可以選參數 ES5 中的形參和實參可以不一致,但是在ts中必須一樣;
- 如果不一樣就需要配置可選參數;
- 可選參數必須配置到最后;
可選參數后面使用問號表示;
默認參數
function getInfo(name:string,age:number=20):string{if(age){return `${name}---${age}`}else{return `${name}---`} } getInfo('zhansan',9999);剩余參數
舉例說明
使用剩余參數后
如果使用多個參數,且包含剩余參數的函數
剩余參數必須放到最后面;
ts函數重載
Java中的方法重載,指的是兩個或者兩個以上同名的函數,但是它們的參數是不一樣的,這時候就會出現函數重載;
typescript中的重載,通過一個函數提供多個函數類型定義來實現重載;
ES5中出現同名的方法,下面的會替換上面的方法;
TS中的實現
也存在參數可選的情況下重載
箭頭函數
箭頭函數的this,始終指向上下文的實例;
(4)類
ES5的類
function Person{this.name = 'zhansan';this.age = 20; } var p = new Person(); console.log(p.name);ES5構造函數 和 原型鏈 里面增加方法
function Person{this.name = 'zhansan';this.age = 20;this.run = function(){console.log(this.name);} } Person.prototype.sex = 'man'; Person.prototype.work = function(){console.log(this.name + "在工作"); } var p = new Person(); p.work();如上圖:原型鏈上面的方法可以背實例共享,但是構造函數的不會;
ES5增加靜態方法
function Person{this.name = 'zhansan';this.age = 20;this.run = function(){console.log(this.name);} } Person.getInfo = function(){console.log("23456789); }; // 使用靜態方法 Person.getInfo();(5)繼承
ES5繼承----對象冒充繼承
function Person{this.name = 'zhansan';this.age = 20;this.run = function(){console.log(this.name);} } Person.prototype.sex = 'man'; Person.prototype.work = function(){console.log(this.name + "在工作"); }//定義一個其他方法 function Dog(){Person.call(this); }//使用繼承的方法 var p = new Dog(); p.run(); // p.work(); 不可以繼承的實現: 對象冒充可以繼承構造函數里面的屬性和方法,但是不能繼承 原型鏈的方法;
ES5繼承----原型鏈繼承
function Person{this.name = 'zhansan';this.age = 20;this.run = function(){console.log(this.name);} } Person.prototype.sex = 'man'; Person.prototype.work = function(){console.log(this.name + "在工作"); }//定義一個其他方法 function Dog(){console.log('我是好人’); }//使用繼承的方法 Dog.prototype = new Person(); var dog = new Dog(); dog.work(); dog.run();原型鏈的問題:實例化的時候 沒法給父類傳參;
ES5繼承----原型鏈+構造函數 繼承
function Person{this.name = 'zhansan';this.age = 20;this.run = function(){console.log(this.name);} } Person.prototype.sex = 'man'; Person.prototype.work = function(){console.log(this.name + "在工作"); }//定義一個其他方法 function Dog(name, age){Person.call(this,name,age); }//使用繼承的方法 Dog.prototype = new Person(); var dog = new Dog('zhangsan',89); dog.work(); dog.run();組合繼承可以實現上面兩種方式都使用的功能;
TS里面定義類
class Person{name:string;construct(n:string){ // 實例化的時候會觸發constructthis.name = n;}run():void{console.log(this.name);} } var p = new Person('zhansan'); p.run();TS里面的繼承
ts中如何實現繼承 (extends / super)
class Person{name:string;construct(n:string){ // 實例化的時候會觸發constructthis.name = n;}run():void{console.log(this.name);} }class Dog extends Person{construct(n:string){ super(name); //構造函數和super都要有;super 相當于 調用父類的構造函數} } var p = new Dog('zhansan'); p.run();繼承這里明顯的ts比js要簡單;
(6)類里面的修飾符
舉例:private的使用
子類 和 類外部 都無法使用,只能在當前類 內部使用;
舉例:private的使用
(7)靜態屬性 與 靜態方法
ES5的 靜態屬性 和 靜態方法
靜態屬性 和 靜態方法都是直接綁定在函數上面的,實例屬性和實例方法都是在函數內部的;
TS的 靜態屬性 和 靜態方法
class Person{public name:string;public age:number = 20;constructor(name:string){this.name = name;}run(){ // 實例方法console.log(this.name + "123456");}work(){ // 實例方法console.log(this.name+"098765");}static print(){ // 靜態方法console.log(this.name+"098765-"+ this.age);} } var p = new Person(); p.run(); // 使用實例方法 Person.print(); //使用靜態方法1- 實例方法 必須在外部實例化以后才能使用;
2- 實例方法 前面加上static 就會變成靜態方法;
3- 靜態方法不能使用基本屬性,只能使用靜態屬性;
多態
父類定義一個方法不去實現,讓繼承它的子類去實現,每個子類都有不同的表現;
(8)抽象方法
(1)抽象類
標準:一個類要求它的字類必須包含指定方法,它是提供其他類繼承的基類,不能被直接實例化。
定義抽象類:
abstract class Animal {abstract eat():any ; }let a=new Animal(); // 報錯:無法創建抽象類的實例(2)抽象方法
抽象方法在子類里面必須實現
// 父類 abstract class Animal {public name: string;constructor(name: string) {this.name = name;}abstract eat(): any; } // 子類Dog class Dog extends Animal {constructor(name: string) {super(name);}// 抽象類的子類必須實現抽象類里面的抽象方法eat() {console.log(this.name + '在吃肉');} } let d = new Dog('達摩'); d.eat();// 子類Cat class Cat extends Animal { constructor(name: string) {super(name);} }子類Cat不實現eat()方法,會報錯:非抽象類“Cat”不會實現繼承自“Animal”類的抽象成員“eat”,即子類Cat不會自動繼承父類的方法
注意點:
(9)接口
另一個我覺得還不錯的解釋;
定義方法:
定義方法(參數限定):
function print(label:string):void{console.log('12345678'); } print();定義方法(JSON參數限定):
接口實現:
作用:對批量方法傳入參數進行約束;
interface FullName{first:string, // 接口屬性second:string } function name(name:FullName){ console.log(name.first + ''----"+ name.second); }// name('23456'); 錯誤寫法 var obj = { //必須傳入 first,secondage:20,first:'zhangsan',second:'siwu' }name(obj);傳入的對象必須包含接口需要實現的參數;
接口批量實現:
接口可選參數:
1、實現接口的參數的順序可以不同,但是必須要有;
2、可選的參數后面帶一個問號,表示參數可以傳可以不傳;
模擬ajax
定義一個接口:
實現這個接口:
調用接口:
(9)函數型接口
作用:對方法傳入的參數,以及返回值進行約束;
interface encrypt{(key:string,value:string):string } var md5:encrypt = function(key:string,value:string):string{return key+value } md5('name','zhangsan');舉例: 兩種加密方式
(10)可索引接口
可索引接口,是數組,對象的約束(不常用)
索引必須是number
interface User{[index:number]:string } var arr:User = ['aa','bb']; console.log(arr[0]);索引必須是string
interface User{[index:string]:string } var arr:User = {name:'zhangsan'};(11)類類型接口
對類的約束 和 抽象類有點像
方法必須實現,但是參數也可以不傳;
(12)接口拓展
接口可以繼承接口
interface Animal{eat():void; } interface Dog entends Animal{work():void; } class Preson implements Dog{public name:string;construtor(name:string){this.name = name;}eat(){}work(){} }實現一個繼承類和繼承接口同步的
(13)泛型函數
泛型: 可以支持不特定的數據類型; 要求:傳入的參數和返回的參數一致;
舉例:只能返回string類型
方法一:
使用any可以實現,但是相當于放棄了類型檢查;
上面可以返回 string,和 number;
第二種:使用泛型
傳入的參數和返回的參數一致;
這里 可以使用T 也可以使用別的字符串,但是必須保證三個一致;
返回類型可以是任意類型實現
將返回值的類型設置成any即可;
(14)泛型類
舉例:比如有一個算法,需要同時支持返回數字和返回字符串兩種類型,就可以通過范型類來實現;
如上面所示只能返回一種類型;
使用范型類
(15)泛型接口
先看看函數類型接口
第一種:
第二種:
本人更喜歡第一種模式;
(16)泛型類
使用JS寫法
使用普通類
使用范型類
(17)TS模塊
舉例實現:
1、創建數據庫
也可以使用另一種暴露方式
2、調用數據庫的內容
(18)命名空間
命名空間里面的方法要使用,必須暴露出去;
調用命名空間的方法
訪問多個命名空間
(19)裝飾器
(20)類裝飾器
傳遞的參數params就是當前的類;
如上圖:舉例拓展一個屬性,在這類的基礎上拓展一個apiUrl屬性;還可以拓展方法,如下圖
拓展類傳遞參數:
如上圖所以:target代表要裝飾的類,params代表裝飾器傳遞的參數;
在裝飾器里面拓展原始類的屬性
類裝飾器的構造函數
修改構造函數 的數據
如果loginClass爆紅 是因為getData()沒有重載;
(21)屬性裝飾器
修改屬性的值
(22)方法修飾器
舉例測試拓展類
修改當前方法
(23)方法參數修飾器
總結
- 上一篇: 性能优化之图片懒加载
- 下一篇: npm -S -D的区别