2019-10-08 11:28:24 6454瀏覽
TypeScript是一種由微軟開發的自由和開源的編程語言。它是JavaScript的一個超集,而且本質上向這個語言添加了可選的靜態類型和基于類的面向對象編程。本篇文章扣丁學堂HTML5培訓小編就從安裝TypeScript環境出發,結合具體的實例來深入探索TypeScript。
1、安裝
npminstall-gtypescript
項目目錄終端執行tsc--init 更改tsconfig.json“outDir”:“./js”
1、數據類型
布爾值 數字 字符串 數組 元組Tuple 枚舉 Any Void(函數沒有返回值使用。) Null和Undefined(默認情況下null和undefined是所有類型的子類型。) Never(never類型是任何類型的子類型) Object
2、函數
聲明函數 functionrun():string{ return'typescript'; } 匿名函數 varfun=function():string{ return'typescript'; } 定義方法傳參 functionuser(name:string,age:number):string{ return`${name}----${age}`; } varuser=function(name:string,age:number):string{ return`${name}----${age}`; } 沒有返回值 functionrun():void{ console.log('typescript'); } 方法可選參數 functionuser(name:string,age?:number):string{ return`${name}----${age}`; } 方法參數默認值 functionuser(name:string,age:number=20):string{ return`${name}----${age}`; } 方法剩余參數 functionuser(...result:number[]):string{ } functionuser(name:string,...result:number[]):string{ } 重載 functionuser(name:string):string; functionuser(age:number):number; functionuser(str:any):any{ if(typeofstr==='string){ returnstr }else{ returnstr } }
基本模型 classPerson{ name:string;//屬性省略publick關鍵詞 constructor(name:string){//構造函數實例化的時候調用的方法(初始化對象) this.name=name; } run():void{ alert(this.name); } } classPerson{ name:string;//屬性省略publick關鍵詞 constructor(name:string){//構造函數實例化的時候調用的方法(初始化對象) this.name=name; } setName():void{ this.name=name; } getName():string{ alert(this.name); } } varperson1=newPerson('張三'); alert(person1.getName()); person1.setName('李四'); alert(person1.getName());
classPerson{ name:string;//屬性省略publick關鍵詞 constructor(name:string){//構造函數實例化的時候調用的方法(初始化對象) this.name=name; } run():string{ return`${this.name}` } } 子類可以使用父類的屬性和方法如果子類的方法或者屬性和父類相同則以子類為主 classWebextendsPerson{ constructor(name:string){ super(name);//初始化父類的構造函數 } work():string{ return`${this.name}在運動` } run():string{ return`${this.name}` } } varw=newWeb('李四'); alert(w.run());
public
共有類型在類里面、子類、類外面都可以訪問(默認,不寫默認就是)。
保護類型在類里面、子類可以訪問,類外面都不可以訪問。
私有類型在類里面可以訪問,子類和類外面都不可以訪問。
static(靜態方法里面不能直接調用類里面的屬性,能調用靜態屬性)
classPerson{ publicname:string; staticage:number=20; constructor(name){ this.name=name; } run(){ alert(`${this.name}在運動`); } staticprint(){ alert(`print`+Person.age); } }
父類定義一個方法不去實現,讓繼承它的子類去實現,讓每一個子類有不同的表現
classAnimal{ name:string; constructor(name:string){ this.name=name; } eat(){ console.log('吃的方法'); } } classDogextendsAnimal{ constructor(name:string){ super(name) } eat(){ returnthis.name+'骨頭' } } classCatextendsAnimal{ constructor(name:string){ super(name) } eat(){ returnthis.name+'魚' } }
提供標準
abstract抽象類不能實例化為子類提供基類
子類必須實現父類的抽象方法
abstract必須放在抽象類里面
abstractclassAnimal{ name:string; constructor(name:string){ this.name=name; } abstracteat():any; } classDogextendsAnimal{ constructor(name:any){ super(name); } eat(){ console.log(this.name); } }
定義規范定義行為和動作的規范(接口不關心類內部的數據狀態和方法實現的細節)
interfaceFullName{ firstName:string; secondName:string; } functionprintName(name:FullName){ console.log(name.firstName+'--'+name.secondName) } varobj={ firstName:'sun', secondName:'yu' } printName(obj)//ok 接口的可選屬性 interfaceFullName{ firstName:string; secondName?:string; } functionprintName(name:FullName){ console.log(name.firstName+'--'+name.secondName) } varobj={ firstName:'sun', secondName:'yu' } printName(obj)//ok varobj={ firstName:'sun' } printName(obj)//ok 函數類型的接口 interfaceencrypt{ (key:string,value:string):string; } varmd5:encrypt=function(key:string,value:string):string{ returnkey+value; } md5('key','value'); 可索引接口數組和對象的約束(不常用) interfaceuserArr{ [index:number]:string } vararr:userArr=['string','string'];//ok interfaceuserObj{ [index:string]:string } vararr:userObj=['string','string'];//ok 類類型接口對類的約束 interfaceAnimal{ name:string; eat(str:string):void; } classDogimplementsAnimal{ name:string; constructor(name:string){ this.name=name; } eat(){ return`吃骨頭`; } } vardog=newDog('小黑'); dog.eat(); 接口擴展接口擴展接口 interfaceAnimal{ eat():void; } interfacePersonextendsAnimal{ work():void; } classWebimplementsPerson{ publicname:string; constructor(name:string){ this.name=name; } eat(){ console.log(this.name+'喜歡吃饅頭'); } work(){ console.log(this.name+'愛工作'); } } --------------------------- interfaceAnimal{ eat():void; } interfacePersonextendsAnimal{ work():void; } classprogrammer{ public:name:string; constructor(name:string){ this.name=name; } coding(code:string){ console.log(this.name+code); } } classWebextendsprogrammerimplementsPerson{ constructor(name:string){ super(name) } eat(){ console.log(this.name+'喜歡吃饅頭'); } work(){ console.log(this.name+'愛工作'); } }
interfaceFullName{ firstName:string; secondName:string; } functionprintName(name:FullName){ console.log(name.firstName+'--'+name.secondName) } varobj={ firstName:'sun', secondName:'yu' } printName(obj)//ok 接口的可選屬性 interfaceFullName{ firstName:string; secondName?:string; } functionprintName(name:FullName){ console.log(name.firstName+'--'+name.secondName) } varobj={ firstName:'sun', secondName:'yu' } printName(obj)//ok varobj={ firstName:'sun' } printName(obj)//ok 函數類型的接口 interfaceencrypt{ (key:string,value:string):string; } varmd5:encrypt=function(key:string,value:string):string{ returnkey+value; } md5('key','value'); 可索引接口數組和對象的約束(不常用) interfaceuserArr{ [index:number]:string } vararr:userArr=['string','string'];//ok interfaceuserObj{ [index:string]:string } vararr:userObj=['string','string'];//ok 類類型接口對類的約束 interfaceAnimal{ name:string; eat(str:string):void; } classDogimplementsAnimal{ name:string; constructor(name:string){ this.name=name; } eat(){ return`吃骨頭`; } } vardog=newDog('小黑'); dog.eat(); 接口擴展接口擴展接口 interfaceAnimal{ eat():void; } interfacePersonextendsAnimal{ work():void; } classWebimplementsPerson{ publicname:string; constructor(name:string){ this.name=name; } eat(){ console.log(this.name+'喜歡吃饅頭'); } work(){ console.log(this.name+'愛工作'); } } --------------------------- interfaceAnimal{ eat():void; } interfacePersonextendsAnimal{ work():void; } classprogrammer{ public:name:string; constructor(name:string){ this.name=name; } coding(code:string){ console.log(this.name+code); } } classWebextendsprogrammerimplementsPerson{ constructor(name:string){ super(name) } eat(){ console.log(this.name+'喜歡吃饅頭'); } work(){ console.log(this.name+'愛工作'); } }
模塊的概念(官方):”內部模塊“=》”命名空間“,”外部模塊“=》”模塊“模塊在其自身的作用域里面執行,而不是在全局作用域執行。這就意味著定義一個模塊里的變量,函數,類等等在模塊外部是不可見的,除非你明確的使用export形式之一導出他們。相反,如果想使用其他模塊導出的變量,函數,類,接口等的時候,你必須要導入它們,可以使用import形式之一。
模塊的概念(自己理解):我們可以把一些公共的功能單獨抽離成一個文件作為一個模塊。模塊里面的變量,函數,類等都是私有的,如果我們要在外部訪問模塊里面的數據(變量,函數,類),我們需要通過export暴露模塊里面的數據(變量、函數、類)暴露后我們通過import引用模塊里面的數據(變量,函數,類)。
定義db.ts vara:string="string"; functiongetData(value:string):string{ returnvalue } export{ a, getData } 使用 import{a,getDate}form'./db' getData(); import{a,getDataasget}form'./db' get(); 定義db.ts exprotdefaultfunctiongetData(value:string):string{ returnvalue } 使用 importgetDataform'./db' getData();
命名空間和模塊的區別:命名空間,內部模塊,主要用于組織代碼,避免命名沖突。模塊,ts的外部模塊的簡稱,側重代碼的復用,一個模塊里可能會有多個命名空間。
namespaceA{ interfaceAnimal{ name:string; eat(str:string):void; } exportclassDogimplementsAnimal{ name:string; constructor(name:string){ this.name=name; } eat(){ return`吃骨頭`; } } } vardog=A.Dog("小黑"); dog.eat(); 命名空間封裝成模塊 a.ts文件名 定義 exportnamespaceA{ interfaceAnimal{ name:string; eat(str:string):void; } exportclassDogimplementsAnimal{ name:string; constructor(name:string){ this.name=name; } eat(){ return`吃骨頭`; } } } 使用 import{a}from'./a' vardog=newa.Dog(); dog.eat();
裝飾器:裝飾器是一種特殊類型的聲明,它能夠被附加到類聲明,方法,屬性或參數上,可以修改類的行為。
通俗的講裝飾器就是一個方法,可以注入到類、方法、屬性參數上來擴展類、屬性、方法、參數的功能。
常見的裝飾器有:類裝飾器、屬性裝飾器、方法裝飾器、參數裝飾器。
裝飾器寫法:普通裝飾器(無法傳參)、裝飾器工廠(可傳參)。
裝飾器是過去幾年中js最大的成就之一,已經是Es7的標準特性之一。
1.類裝飾器(普通裝飾器,無法傳參) functionlogClass(params:any){ console.log(params); params.prototype.apiUrl="動態擴展的屬性"; params.prototype.run=function(){ console.log("我是run方法"); } } @logClass httpClient{ constructor(){ } getData(){ } } varH=newhttpClient(); console.log(H.apiUrl); H.run(); 2.類裝飾器(裝飾器工廠,可傳參) functionlogClass(params:string){ returnfunction(target:any){ target.prototype.apiUrl="動態擴展的屬性"; target.prototype.run=function(){ console.log("我是run方法"); } } } @logClass('hello') httpClient{ constructor(){ } getData(){ } } 把類賦值給target 把參數賦值給params varH:any=newhttpClient(); console.log(H.apiUrl); H.run(); 類裝飾器重載以前類的構造函數 functionlogClass(target:any){ console.log(target); returnclassextendstarget{ apiUrl:any="我是修改后的url"; getData(){ console.log(this.apiUrl); } } } @logClass httpClient{ publicapiUrl:string|undefined; constructor(){ this.apiUrl='url'; } getData(){ console.log(this.apiUrl); } } varhttp=newhttpClient(); ------------------------------ 3.屬性裝飾器(屬性裝飾器表達式會在運行時當作函數調用,傳入下列兩個參數,對于靜態成員來說是類的構造函數,對于實例成員是類的原型對象) functionlogClass(params:any){ console.log(params); params.prototype.apiUrl="動態擴展的屬性"; params.prototype.run=function(){ console.log("我是run方法"); } } functionlogProperty(params:string){ returnfunction(target:any,attr:any){ console.log(target); console.log(target[attr]); target[attr]=params; } } @logClass('xxx') httpClient{ @logProperty("http://baidu.com"); publicurl:string|undefined; constructor(){ } getData(){ console.log(this.url); } } varhttp=newhttpClient(); http.getData(); 4.方法裝飾器 它會被應用到的方法的屬性描述符上,可以用來監視,修改或者替換方法定義 方法裝飾器會在運行是傳入下列3個參數 (1)對于靜態成員來說類的構造函數,對于實例成員來說是類的原型對象。 (2)成員的名字。 (3)成員的屬性描述符。 functionlogMethod(params:any){ returnfunction(target:any,methodName:any,desc:any){ console.log(target); console.log(methodName); console.log(desc); target.apiUrl="動態擴展的屬性"; target.run=function(){ console.log("我是run方法"); } } } httpClient{ constructor(){ } @logMethod("http://baidu.com") getData(){ console.log(this.url); } } varhttp:any=newhttpClient(); http.run(); ------------------------------------------ functionlogMethod(params:any){ returnfunction(target:any,methodName:any,desc:any){ console.log(target); console.log(methodName); console.log(desc); //修改裝飾器的方法把裝飾器方法傳入所以參數改為string類型 //保存當前的方法 varoMethod=desc.value; desc.value=function(...args:any[]){ args=args.map((value)=>{ returnString(value) }); console.log(args); } } } httpClient{ publicurl:any|undefined; constructor(){ } @logMethod("http://baidu.com") getData(){ console.log(this.url); } } varhttp:any=newhttpClient(); http.getData(123,'xxx');
【關注微信公眾號獲取更多學習資料】 【掃碼進入HTML5前端開發VIP免費公開課】