這篇文章主要介紹“TypeScript入門知識(shí)點(diǎn)有哪些”,在日常操作中,相信很多人在TypeScript入門知識(shí)點(diǎn)有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”TypeScript入門知識(shí)點(diǎn)有哪些”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
成都創(chuàng)新互聯(lián)主要從事網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)廣西,10年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):18980820575
ts是什么?ts其實(shí)是TypeScript的一個(gè)簡(jiǎn)稱,就跟JavaScript簡(jiǎn)稱為js一樣,官方給的解釋是,ts它是js的超集,其實(shí)js的代碼本質(zhì)上都是ts編譯的,例如寫一個(gè)js代碼 document.write() ,上面的提示就是ts,如圖:
系統(tǒng)里面寫的是ts代碼,所以ts是js的超集,是給js添加拓展功能的語(yǔ)言,這樣的語(yǔ)言曾經(jīng)還有一個(gè)叫as,但是這個(gè)語(yǔ)言已經(jīng)沒了,它其實(shí)就是flash語(yǔ)言。但我么開發(fā)需要完善js的話,必須得有這樣的一個(gè)東西,所以微軟拿著這個(gè)as的語(yǔ)法開發(fā)了ts這個(gè)語(yǔ)言,也就是說as和ts的語(yǔ)法基本是一樣的,只不過ts是微軟開發(fā)的,然后推廣的不錯(cuò),現(xiàn)在隨著我們編程越來(lái)越全民化,ts使用的也就越來(lái)越多,包括在找工作中,如果你的薪資是在12k以上的話,基本上都會(huì)問你會(huì)不會(huì)ts,現(xiàn)在的編程很多情況下都是用到ts,因?yàn)樗芙ojs添加拓展功能,
比如:可以進(jìn)行各種各樣的模塊化開發(fā),像之前提到的AMD,CMD開發(fā),CommonJS,es6的模塊化規(guī)范。假設(shè)現(xiàn)在在客戶端開發(fā),有沒有一種開發(fā)場(chǎng)景,既可以用AMD,也可以用CMD,CommonJS,es6的,
答案是沒有,因?yàn)镃ommonJS是只能在nodejs中使用,es6的模塊化開發(fā)只能在服務(wù)器中用,它們都是有各自限制的。
但是ts中,想用什么都可以,它是支持全場(chǎng)景的。ts它更像后端,他的語(yǔ)法跟java最相似,這樣有什么好處?大家知道js是弱類型語(yǔ)言,比如一個(gè)變量先定義一個(gè)數(shù)字型,然后再重新賦值一個(gè)字符串型的,這樣的話這個(gè)變量的類型就改變了,這種弱類型開發(fā)是對(duì)項(xiàng)目有一定的安全隱患的,
比如就用這個(gè)變量去做其他事情,它有可能變成其他類型的數(shù)據(jù),所以對(duì)開發(fā)來(lái)說是有安全隱患的,所以必須得有ts來(lái)規(guī)范js開發(fā),消除這個(gè)安全隱患,這就是為什么ts像java、#c這些后端語(yǔ)言,這些強(qiáng)類型語(yǔ)言定義變量的時(shí)候,需要先聲明這些變量的類型是什么,一旦定義這個(gè)變量的類型后,后期是不允許修改類型的,有了這樣的規(guī)范約束后,開發(fā)就更加安全了。
現(xiàn)在ts使用的場(chǎng)景是非常廣泛:js的提示(編輯器內(nèi)置了規(guī)范語(yǔ)法的ts),主流框架vue,react在底層寫框架的時(shí)候用的也是ts。
說這么多,下面直接介紹ts,也就是TypeScript。
ts是一個(gè)給js添加特性的擴(kuò)展語(yǔ)言。
TypeScript是由微軟開發(fā)的一款開源的編程語(yǔ)言。
TypeScript是JavaScript的超集,遵循最新的es6、es5規(guī)范。TypeScript擴(kuò)展了JavaScript的語(yǔ)法。
TypeScript更像后端java、C#這樣的面向?qū)ο笳Z(yǔ)言,可以讓js開發(fā)大型企業(yè)項(xiàng)目。
谷歌也在大力支持TypeScript的推廣,谷歌的angular2.x+就是基于TypeScript語(yǔ)法。
最新的vue、React也可以集成TypeScript。
nodeJs礦建Nestjs、midway中用的就是TypeScript語(yǔ)法。
能給js增加的功能有
類型批注和編譯時(shí)類型檢查
類型推斷
類型擦除
接口
枚舉
Mixin
泛型編程
名字空間
元組
Await
類
模塊
lambda 函數(shù)的箭頭語(yǔ)法
可選參數(shù)以及默認(rèn)參數(shù)
js 是一個(gè)弱類型的語(yǔ)言,但ts是強(qiáng)類型的,語(yǔ)法很相像,但ts算是擴(kuò)展的js的語(yǔ)法,ts通過類型注解,提供編譯js時(shí)的靜態(tài)類型檢查。
ts無(wú)法直接運(yùn)行,所以只能編譯成js運(yùn)行。類似sass用來(lái)編譯css,不能直接運(yùn)行。
編譯工具 - typescript
在全局任意位置下,先檢測(cè)是否安裝過ts
tsc --version
npm install -g typescript
檢測(cè)是否安裝成功:
tsc -v
ts文件的后綴是ts,編譯命令:
tsc 被編譯的文件
會(huì)在被編譯文件的同級(jí)目錄下生成一個(gè)同名的js文件。
生成自定義名稱路徑的文件:
tsc 被編譯的文件 --outFile 編譯后的文件路徑
初始化命令:
tsc --init
執(zhí)行初始化命令后,會(huì)生成一個(gè)tsconfig.json文件,如下:
其中常用配置項(xiàng)說明:
代表ts要轉(zhuǎn)換后js版本
"target": "es5"
如果ts是以模塊形式書寫的,使用什么樣的模塊化規(guī)范,默認(rèn)是commonJS
"module": "amd"
配置輸出目錄,可自己設(shè)置
"outDir": "./"
上面的配置項(xiàng)配置好以后,執(zhí)行監(jiān)視命令會(huì)自動(dòng)編譯:
tsc -w
使用amd規(guī)范的時(shí)候,需要將require.js文件拷貝到項(xiàng)目根目錄下,且需要一個(gè)出口文件:
將ts編譯成js,自動(dòng)生成目標(biāo)js文件
tsc 目標(biāo)js文件
在定義變量的時(shí)候需要指定類型,且定義好類型以后就不能改變他的類型了 - 強(qiáng)類型。
let decLiteral: number = 6; // 十進(jìn)制 let hexLiteral: number = 0xf00d; // 16進(jìn)制 let binaryLiteral: number = 0b1010; // 二進(jìn)制 let octalLiteral: number = 0o744; // 8進(jìn)制 let num: Number = 5; // 此時(shí)大寫Number類型可以賦值為數(shù)值對(duì)象類型 num = new Number(10);
let isDone: boolean = false;let bool: Boolean = true; // 首字母大寫的類型可以賦值為對(duì)象類型
boolean這種類型只能賦值兩個(gè)值:true/false
var bool: boolean = true var bool: boolean = new Boolean(true)
Boolean這種類型除了上面的字面量方式的兩個(gè)值,還可以使用構(gòu)造函數(shù)方式
var bool: Boolean = false;var bool: Boolean = new Boolean(true)
var str: string = 'asdfasdf';var str1: String = new String('43563456')
ts寫的數(shù)組,其中的數(shù)據(jù)必須是同一個(gè)類型,但不指定長(zhǎng)度
數(shù)組中所有數(shù)據(jù)的值類型必須是數(shù)字
var arr: number[] = [1,2,3];var arr: Array= ['a','b'];
聲明二維數(shù)組
var arr: number[]var brr: number[][] = [ [1,2,3], [4,5,6]];
ts中的元組表示不同類型數(shù)據(jù)組成的集合,通常會(huì)固定長(zhǎng)度,同樣可以使用下標(biāo)訪問元素和給元素賦值
元組中就可以放不同類型的數(shù)據(jù)
元組在定義的時(shí)候就將長(zhǎng)度固定了
var x: [string,number] = ['a',2];console.log(x);console.log(x[0]);
錯(cuò)誤
x[2] = 20
不能加長(zhǎng)度
let x: [string, number];x = ['hello', 10];x[2] = 'world'; // 不能加長(zhǎng)度
可以給元素push一個(gè)值,這個(gè)值必須是string或number的類型,其他類型不允許
x.push('aaaa')
錯(cuò)誤
x.push(true) // 錯(cuò)誤
當(dāng)給元組中并不存在的下標(biāo)進(jìn)行賦值的時(shí)候,會(huì)使用聯(lián)合類型:
x[3] = 'world'; // OK, 字符串可以賦值給(string | number)類型x 6] = true;// Error, 布爾不是(string | number)類型
ts中的枚舉相當(dāng)于在定義變量類型,這個(gè)類型有固定的取值范圍,默認(rèn)值從0開始,向后遞增,使用指定的鍵來(lái)?yè)Q換取到值,如果一個(gè)變量使用了這個(gè)類型,那他的值就必須從這個(gè)類型中選擇,不能隨便賦值:
枚舉 - 必須使用指定的集合中的值
枚舉類型,其實(shí)是給數(shù)字起了一些名字,讓我們可以通過這個(gè)名字獲取到對(duì)應(yīng)的數(shù)字
默認(rèn)情況,第一個(gè)名字對(duì)應(yīng)的值是0,依次向后遞增
enum Color {Red,Green,Blue};var c: Color = Color.Blue; // 2
如果給其中某一個(gè)名字賦值了,他后面的名字對(duì)應(yīng)的值,是根據(jù)這里的值向后遞增
enum Color {Red,Green = 5,Blue};var c: Color = Color.Blue; // 6
每個(gè)值可以指定
enum Color {Red=3,Green = 4,Blue=2}; var c: Color = Color.Blue; // 2
可以指定非數(shù)字的值
enum Color {Red='男',Green = '女',Blue='不男不女'};var c: Color = Color.Blue; // 不男不女
通過對(duì)應(yīng)值的數(shù)字獲取到對(duì)應(yīng)的名字 - 名字是字符串類型
enum Color {Red,Green=5,Blue};var c: string = Color[6] // Blue
如果我們指定了其中的值是非數(shù)字型的,就不能使用這個(gè)騷操作了
enum Color {Red='red',Green = 'green',Blue='blue'};var c: string = Color['red']; // 這個(gè)地方的值必須是數(shù)字才行
Any類型,表示弱類型,也就是當(dāng)我們定義一個(gè)變量的時(shí)候,不能確定變量值的類型的時(shí)候,這個(gè)類型我們又愛又恨
使用:
var a:any = 20var b:any = 'asdfasdf'var c:any = [1,2,3]
注意:本來(lái)我們使用ts編寫代碼,為的是限制類型,減少安全隱患,但是如果使用了any類型,就跟直接寫js一樣了,失去了意義,所以若非迫不得已,盡量不要使用。
這種類型,一般用于函數(shù)執(zhí)行后,不使用return返回結(jié)果的時(shí)候,就指定返回結(jié)果是void
聲明變量的時(shí)候不使用它 - 當(dāng)函數(shù)沒有返回值的時(shí)候,返回類型指定為void
function fn(a:number,b:number):void{ console.log(a*b);}
這種類型主要用于參數(shù)和返回值,用于變量毫無(wú)意義,因?yàn)槎x一個(gè)變量指定為undefined類型時(shí),以后也就只能是undefined類型了,函數(shù)中的用法:
function fn(num:number|undefined):number|undefined{ return num;}
undefined - 未定義類型
var a:undefined = undefined
定義變量不用undefined,因?yàn)槎x了沒有用
通常會(huì)用在函數(shù)的參數(shù)里面
希望fn函數(shù)的參數(shù)a是可選項(xiàng)
function fn(a:number|undefined):void{ console.log(a);}fn(undefined)
函數(shù)可選項(xiàng)
參數(shù)名后面,類型的冒號(hào)之前加 ? 表示這個(gè)參數(shù)是可選項(xiàng)
undefined通常用在函數(shù)返回值,如果返回的是undefined就需要在返回值的地方指定undefined類型
function fn(a?:number):number|undefined{ return a;}fn()
null類型 - 空 - 這個(gè)數(shù)據(jù)要被銷毀啦
通常在定義復(fù)雜數(shù)據(jù)類型,且在后期需要給賦值為null的時(shí)候使用
var a:number|null = 10;
使用變量a計(jì)算 - 完成
讓內(nèi)存回收這個(gè)變量
a = null
never類型表示永遠(yuǎn)不存在的值的類型,例如,一個(gè)函數(shù)中拋出的錯(cuò)誤,函數(shù)中有死循環(huán)永遠(yuǎn)不可能返回 …
function fn():never{ throw new Error('錯(cuò)誤')}function fn():never{ return fn()}fn()
對(duì)象類型:
var obj: object = { name:"張三"}
錯(cuò)誤寫法 - 對(duì)象默認(rèn)不允許添加鍵值對(duì)
obj.name = '張三';
如果在一段代碼執(zhí)行后的類型種類的可能性比較多,就需要假設(shè)這是一種什么類型 - 這種操作就叫做斷言。
如果一個(gè)表達(dá)式的結(jié)果有可能是多種類型,最終需要肯定其中一種
var abcd: any = [1, 2, 3, 4, 5];
斷言abcd變量是一個(gè)數(shù)組
(abcd as [string,number]).push(6)(abcd as string) += 'ddd'
在ts中,函數(shù)定義比起js中,多了參數(shù)類型和返回值的類型定義:
函數(shù)的定義,參數(shù)的類型聲明,返回值的類型聲明
function fn(a:number,b:number):number{ // console.log(a+b); return a+b}var res = fn(1,2)
參數(shù)默認(rèn)值
function fn(a:number,b:number=3):number{ return a+b}var res = fn(1)
但是在表示參數(shù)為可選項(xiàng)的時(shí)候,寫法稍有不同:
參數(shù)可選項(xiàng) - ?表示可有可無(wú)
function fn(a:number,b?:number):number{ if(!b){ return a+5 } return a+b}// var res = fn(1)var res = fn(1,3)
帶有默認(rèn)值的參數(shù),必須放在所有參數(shù)的最后面
可選項(xiàng)參數(shù),必須放在所有參數(shù)的最后面
展開運(yùn)算符和合并運(yùn)算符同樣可以使用在ts中,但是要注意運(yùn)算符后面的變量的類型設(shè)置。
計(jì)算不定實(shí)參的和
function sum(...arr:Array){ var sum = 0; for(var i=0;i 函數(shù)重載:通過 為同一個(gè)函數(shù)提供多個(gè)函數(shù)類型定義 來(lái)實(shí)現(xiàn)多種功能的目的。例:
function outputName(name:string):string{ return "我叫"+name}var s1 = outputName('張三')console.log(s1);function outputAge(age:number):string{ return "我今年"+age+"歲了"}var s2 = outputAge(12)console.log(s2);有多個(gè)函數(shù)結(jié)構(gòu)非常類似,可以聲明一個(gè)函數(shù)的結(jié)構(gòu),讓函數(shù)遵循這個(gè)結(jié)構(gòu)
function output(name:string):string; 定義了一個(gè)函數(shù)結(jié)構(gòu) - 名字叫output function output(age:number):string; function output(name:any):any { return "我今年"+name+"歲了"; } var res = output(12) console.log(res); var res1 = output('李四') console.log(res1); var res2 = output(true) 報(bào)錯(cuò)的,因?yàn)楹瘮?shù)的結(jié)構(gòu)要求是參數(shù)string或number console.log(res2);ts中的類
定義
定義方式跟es6的定義方式類似
class 類名{ constructor(){ }}class Person{ // 靜態(tài)屬性 - 用類名直接調(diào)用的屬性 static weight:number; // 類的屬性要定義在這里 name:string; // 表示類中有一個(gè)屬性叫name // 在ts類中,屬性和方法前面可以加一個(gè)修飾符: /* public - 公開的 - 在哪里都能用 protected - 受保護(hù)的 private - 私有的 */ public age:number; // public可以省略的 protected sex:string; // 受保護(hù)的只能在類里面用,類的外面不能用的 private height:number; // 私有的只能在類里面使用,類外面不能用 constructor(name:string,age:number,sex:string,height:number,weight:number){ // 給屬性賦值的時(shí)候,必須在這個(gè)類中是本來(lái)就有這個(gè)屬性才行 this.name = name this.age = age this.sex = sex this.height = height; // this.weight = weight; Person.weight = weight; this.init() } private init(){ // console.log(this.age); // console.log(this.sex); console.log(this.height); console.log("這是初始化方法"); } static fly(){ console.log("飛的更高"); } } var p = new Person('張三',12,'男',120,150) console.log(p); // console.log(p.age); // console.log(p.sex); // 受保護(hù)的屬性不能類的外面使用 // console.log(p.height) // 私有屬性不能類的外面使用 // p.init() console.log(Person.weight); Person.fly()繼承
ts中類的繼承和es6的繼承是一樣,使用extends關(guān)鍵字,然后在構(gòu)造函數(shù)中調(diào)用super函數(shù)相當(dāng)于在調(diào)用父類的構(gòu)造函數(shù)。
如果子類和父類有同名的方法,在子類調(diào)用這個(gè)方法的時(shí)候先在子類里面找,如果子類沒有再到父類里面找。
class Person{ // 靜態(tài)屬性 - 用類名直接調(diào)用的屬性 static weight:number; // 類的屬性要定義在這里 name:string; // 表示類中有一個(gè)屬性叫name // 在ts類中,屬性和方法前面可以加一個(gè)修飾符: /* public - 公開的 - 在哪里都能用 protected - 受保護(hù)的 private - 私有的 */ public age:number; // public可以省略的 protected sex:string; // 受保護(hù)的只能在類里面用,類的外面不能用的 private height:number; // 私有的只能在類里面使用,類外面不能用 constructor(name:string,age:number,sex:string,height:number,weight:number){ // 給屬性賦值的時(shí)候,必須在這個(gè)類中是本來(lái)就有這個(gè)屬性才行 this.name = name this.age = age this.sex = sex this.height = height; // this.weight = weight; Person.weight = weight; this.init() } private init(){ // console.log(this.age); // console.log(this.sex); console.log(this.height); console.log("這是初始化方法"); } static fly(){ console.log("飛的更高"); } } var p = new Person('張三',12,'男',120,150) console.log(p); // console.log(p.age); // console.log(p.sex); // 受保護(hù)的屬性不能類的外面使用 // console.log(p.height) // 私有屬性不能類的外面使用 // p.init() console.log(Person.weight); Person.fly()類的修飾符
在類中定義屬性的時(shí)候,提供了3個(gè)修飾符:
public:公有的 - 在類里面、子類中、類的外面都可以訪問
protected:受保護(hù)的 - 在類里面、子類中可以訪問,在類外面不能訪問
private:私有的 - 在類里面可以訪問,在子類和類的外面都不能訪問
靜態(tài)屬性和方法
es5中靜態(tài)方法使用:
// 模擬jquery的封裝function $(element){ return new Ele(element);}$.get = function(obj){ }function Ele(element){ this.element = document.getElementById("#"+element);}Ele.prototype.css = function(attr,value){ if(value){ this.element.style[attr] = value; }else{ return window.getComputedStyle(this.element)[attr]; }}$("#box").css("color","red");在ts中定義靜態(tài)的屬性和方法使用static關(guān)鍵字。在靜態(tài)方法中無(wú)法訪問到普通的屬性,只能訪問到靜態(tài)的屬性。
class Person{ public name:string = "張三"; static age:number = 20; constuctor(){ } static print1(){ console.log(this.name); // 訪問不到 } static print2(){ console.log(Person.name); // 可以訪問到 }}Person.print1();Person.print2();屬性可以設(shè)置為只讀
多態(tài)
面向?qū)ο蟮娜筇攸c(diǎn):封裝、繼承、多態(tài)
含義:多態(tài)就是說,父類定義一個(gè)方法不去實(shí)現(xiàn),讓繼承它的子類去實(shí)現(xiàn),這樣每個(gè)子類都會(huì)有不同表現(xiàn)。多態(tài)其實(shí)也是繼承的一種表現(xiàn)。
// 父類 - 動(dòng)物類class Animal{ public tui:string = "有腿"; public eat(){ console.log("喜歡吃"); } public sport(){ console.log("能走"); } public tuiNum(){ console.log("有多條腿"); }}// 子類 - 人類class Person extends Animal{ sport(){ console.log("直立走"); } tuiNum(){ console.log("兩條腿"); }}var p = new Person();console.log(p.tui); // 有腿p.eat(); // 喜歡吃p.sport(); // 直立走p.tuiNum() // 兩條腿// 子類 - 鳥類class Bird extends Animal{ sport(){ console.log("很少走,通常都在飛"); } tuiNum(){ console.log("兩條腿"); }}var b = new Bird();console.log(b.tui);b.eat();b.sport(); // 很少走,通常都在飛b.tuiNum(); // 兩條腿// 子類 - 狗類class Dog extends Animal{ sport(){ console.log("通常都在跑,很少走"); } tuiNum(){ console.log("4條腿"); }}var d = new Dog();console.log(d.tui);d.eat();d.sport(); // 通常都在跑,很少走d.tuiNum(); // 4條腿效果:
多態(tài)的表現(xiàn) **小總結(jié):**多態(tài)就是多個(gè)子類繼承自同一個(gè)父類,但是每個(gè)子類將繼承下來(lái)的屬性或方法做了改善,最終每個(gè)子類表現(xiàn)出來(lái)的結(jié)果是不一樣的。
多態(tài)其實(shí)源于繼承,也是方法的重載。
抽象類
在實(shí)際工作中,項(xiàng)目負(fù)責(zé)人通常會(huì)寫一些標(biāo)準(zhǔn)(類似于大綱),然后將標(biāo)準(zhǔn)交給具體實(shí)現(xiàn)的攻城獅,由攻城獅將這個(gè)標(biāo)準(zhǔn)進(jìn)行具體化開發(fā)。
ts中的抽象類就是為制作標(biāo)準(zhǔn)的。抽象類不能被實(shí)例化,只能被派生類繼承并實(shí)現(xiàn)。
定義抽象類使用abstract關(guān)鍵字來(lái)修飾類。
abstract class Animate{ public name:string; constructor(name:string){ this.name = name; }}var ani = new Animate("動(dòng)物"); // 報(bào)錯(cuò)class Dog extends Animate{ constructor(name:string){ super(name); }}var d = new Dog("小黃");這種結(jié)構(gòu)沒有意義。跟普通的繼承是一樣的,并不能體現(xiàn)出標(biāo)準(zhǔn)的特殊。在抽象類中通常會(huì)有抽象方法 - 使用abstract修飾的方法。
抽象方法必須在抽象類中,且只需要定義方法結(jié)構(gòu),不要具體的實(shí)現(xiàn)。但是派生類中必須實(shí)現(xiàn)(完善)抽象方法。
abstract class Animate{ public name:string; constructor(name:string){ this.name = name; } abstract eat():void; // 抽象方法}class Dog extends Animate{ constructor(name:string){ super(name); } eat(){ // 實(shí)現(xiàn)了抽象方法 consolelog("小狗吃糧食"); }}這個(gè)結(jié)構(gòu)就能體現(xiàn)出標(biāo)準(zhǔn)的特殊:規(guī)定子類必須包含eat方法。
抽象方法只能放在抽象類中。
抽象類存在的意義就是被其他類繼承,是其他類的基類。
接口
抽象類只能給方法定義標(biāo)準(zhǔn),對(duì)于屬性限制不夠,所以ts設(shè)計(jì)了接口語(yǔ)法,它定義了屬性和方法的規(guī)范,起到限制和規(guī)范的作用。接口并不關(guān)心這些類的內(nèi)部狀態(tài)數(shù)據(jù),也不關(guān)心這些類里方法的實(shí)現(xiàn)細(xì)節(jié),它只規(guī)定這批類里必須提供某些方法,提供這些方法的類就可以滿足實(shí)際需要。
ts的接口跟別的主流服務(wù)器端語(yǔ)言的接口一樣,同時(shí)還增加了更加靈活的接口類型,包括屬性、函數(shù)、可索引和類等。
簡(jiǎn)單來(lái)說,接口也是在定義標(biāo)準(zhǔn),只不過更加靈活和全面。
屬性接口
屬性接口專門為了約束屬性而設(shè)計(jì)。
語(yǔ)法:
interface 接口名稱{ 變量:類型; 變量:類型;}使用方式:
function printInfo(info:接口名稱){ console.log(info.屬性名); // 屬性名必須是接口定義過的,否則報(bào)錯(cuò)}例:
// 以前對(duì)于數(shù)據(jù)的限制// 1.定義方法function printInfo():void{ console.log(123);}printInfo();// 2.傳入?yún)?shù)function printInfo(info:number):void{ console.log(info);}printInfo(123);// 3.傳入的參數(shù)對(duì)json限制function printInfo(info:{name:string}):void{ console.log(info);}printInfo({ name:"張三"});printInfo({ // 錯(cuò)誤示例 - 鍵在函數(shù)中不存在 sex:"男"});// 這種函數(shù)只能對(duì)一個(gè)鍵做限制,要做批量限制很麻煩,要寫很多函數(shù)// 使用接口限制// 1.定義接口interface info { name:string; sex:string;}// 2.定義函數(shù)使用接口類型function printInfo(data:info){ console.log(data.name); console.log(data.sex); // console.log(data.age); // 錯(cuò)誤 - info中沒有age鍵}// 3.使用printInfo({ name:"張三", sex:"男", age:20 // 錯(cuò)誤 - info中沒有age鍵});var obj = { name:"張三", sex:"男", age:20}printInfo(obj); // 正確// 接口可以批量對(duì)變量進(jìn)行約束 - 參數(shù)的順序可以不一樣,但是不能少參數(shù)定義接口中的可選參數(shù):
interface info{ name:string; sex?:string; [propName:string]:any // 這里表示其他屬性也可以加,也可以不加 } // 這個(gè)接口表示name是必須,sex是可選項(xiàng) // 在屬性前面可以使用readonly來(lái)修飾屬性不可以修改例:
// 對(duì)jquery的ajax的封裝$.ajax({ type: "GET", url: "test.json", data: {username:$("#username").val(), content:$("#content").val()}, dataType: "json" });// 定義接口interface Config{ type?:string; url:string; data?:string; dataType?:string;}// 使用接口類型封裝ajaxfunction sendAjax(config:Config){ var xhr = new XMLHttpRequest(); }// 調(diào)用sendAjax({ url:"", });函數(shù)接口
函數(shù)接口是專門為了約束函數(shù)的參數(shù)和返回而設(shè)計(jì)。
語(yǔ)法:
interface 接口名稱{ (參數(shù):類型):返回值類型}例:
// 加密的接口interface encrypt{ (key:string,value:string):string;}var md5:encrypt=function(key:string,value:string):string{ //模擬操作 return key+value;}console.log(md5('name','zhangsan'));可索引接口
可索引接口是對(duì)數(shù)組、對(duì)象等有索引的數(shù)據(jù)做約束。
對(duì)數(shù)組的約束接口:
interface userArr { [index:number]:string; // 表示索引必須為數(shù)字,數(shù)據(jù)必須是字符串}使用:
var arr:userArr = ["張三","李四"]對(duì)對(duì)象的約束:
interface userObj{ [index:string]:string;}使用:
var obj:userObj = {name:"張三"}泛型
泛型:軟件工程中,我們不僅要?jiǎng)?chuàng)建一致的定義良好的API,同時(shí)也要考慮可重用性。 泛型不僅能夠支持當(dāng)前的數(shù)據(jù)類型,同時(shí)也能支持未來(lái)的數(shù)據(jù)類型,這在創(chuàng)建大型系統(tǒng)時(shí)為你提供了十分靈活的功能。
通俗理解:泛型就是解決 類 接口 方法的復(fù)用性、以及對(duì)不特定數(shù)據(jù)類型的支持(類型校驗(yàn))
泛型方法:
function getInfo(value:T):T{ return value;}getInfo (123);getInfo ('aaa'); 例:
// 約束函數(shù)傳入number返回number,傳入string返回string// 以前:function fn(a:number):number;function fn(a:string):string;function fn(a:any):any{ return a;}// 使用泛型function fn(a:T):T{ return a;}fn (234);fn ("abc"); 命名空間
多人合作開發(fā)項(xiàng)目的時(shí)候,避免不了會(huì)有函數(shù)、變量、類等數(shù)據(jù)的命名沖突。但是ts不允許出現(xiàn)同名的類、函數(shù)、變量(const定義的),這時(shí)候就需要使用命名空間來(lái)解決這個(gè)問題。
命名空間其實(shí)就單獨(dú)做一個(gè)作用域,在當(dāng)前命名空間下的數(shù)據(jù)跟別的命名空間下的數(shù)據(jù)重名也不會(huì)產(chǎn)生沖突。
命名空間語(yǔ)法:
namespace A{ // namespace 命名空間名稱{} class Animal{ constructor(){ console.log("A命名空間下的動(dòng)物類"); } }}// 使用動(dòng)物類的時(shí)候A.Animal()例:
命名空間工作中一個(gè)項(xiàng)目都是協(xié)作開發(fā),每個(gè)人負(fù)責(zé)一個(gè)文件,避免不了函數(shù)、變量、類、接口會(huì)重名。
但是在ts文件,不允許類、函數(shù)、let、const 重名
命名空間就是解決這個(gè)問題的。
命名空間:就是開辟自己的作用域// 定義命名空間:namespace 空間名字{} namespace A{ // 相當(dāng)于定義了一個(gè)單獨(dú)的作用域叫A export class Animal{ name:string; constructor(name:string){ this.name = name; } } } namespace B{ export class Animal{ age:number; constructor(age:number){ this.age = age; } } } // 在這里實(shí)例化Animal類 // 使用命名空間:命名空間.數(shù)據(jù) var a = new A.Animal("張三"); console.log(a.name); // 張三 var b = new B.Animal(20); console.log(b.age); // 20從結(jié)果中可以看到,同名的類處在不同的命名空間下是不會(huì)沖突的。
此時(shí),A命名空間就是一個(gè)單獨(dú)的模塊,進(jìn)行模塊化開發(fā)的時(shí)候,需要將命名空間導(dǎo)出,也就是說一個(gè)命名空間就是一個(gè)模塊,而不是一個(gè)單獨(dú)的文件了。
例:
// 導(dǎo)出export namespace A{ // 將命名空間導(dǎo)出 // 相當(dāng)于定義了一個(gè)單獨(dú)的作用域叫A export class Animal{ name:string; constructor(name:string){ this.name = name; } }}導(dǎo)入的時(shí)候,導(dǎo)入當(dāng)前文件,接收命名空間,通過命名空間來(lái)調(diào)用數(shù)據(jù):
// 導(dǎo)入import { A } from "./demo"; // 導(dǎo)入的是一個(gè)命名空間var a = new A.Animal("張三"); // 實(shí)例化那個(gè)Animalts事件封裝
為什么要封裝?
因?yàn)樵趀s5和es6中允許dom元素繼承EventTarget,但是在ts中不允許繼承。
所以需要重構(gòu)EventTarget。
使用dispathEvent來(lái)拋發(fā)事件,需要使用Event。所以重構(gòu)Event。
本質(zhì):觀察者模式。
ts開發(fā)的規(guī)則
開發(fā)的時(shí)候通常都是在使用模塊化開發(fā)
怎么進(jìn)行模塊化開發(fā)?一個(gè)模塊一個(gè)類,通常類的首字母會(huì)大寫,文件名稱和類的名稱保持一致。
封裝
準(zhǔn)備工作:
將ts配置文件中的module選項(xiàng)改成amd。
"module": "amd",更改輸入輸出目錄:
"outDir": "./js", "rootDir": "./ts",新建html,導(dǎo)入amd所使用的require.js。
配置導(dǎo)入文件以及異步推遲加載。
新建MyEvent.ts文件:
import MyTarget from "./MyTarget";export default class MyEvent{ public type:string; [key:string]:any; public myTarget:MyTarget|null = null; public target:MyTarget|null = null; public data:any; constructor(type:string,data:any = null){ this.type = type; }}新建MyTarget.ts
import IListener from "./IListener";import MyEvent from "./MyEvent";export default class MyTarget{ public listenerList:IListener = {}; constructor(){ } addEventListener(type:string,listener:Function):void{ if(!this.listenerList[type]) this.listenerList[type] = []; this.listenerList[type].push(listener); } removeEventListener(type:string,listener:Function):void{ if(!this.listenerList[type]) return; var index:number = this.listenerList[type].indexOf(listener); if(index>-1){ this.listenerList[type].splice(index,1); } } dispathEvent(evt:MyEvent):boolean{ var list:Function[] = this.listenerList[evt.type]; if(!list) return false; evt.myTarget = this; evt.target = this; for(var i:number=0;i新建IListener.ts文件
export default interface IListener{ [key:string]:Array;} 在Main.ts中使用:
import MyEvent from "./MyEvent";import MyTarget from "./MyTarget";var doc = new MyTarget();var ev = new MyEvent("zi");ev.a = 10;// var ev1 = new MyEvent("ziji");// ev1.b = 20;// console.log(doc);doc.addEventListener("zi",handler1);doc.addEventListener("zi",handler2);doc.addEventListener("ziji",handler2);doc.dispathEvent(ev);doc.dispathEvent(ev);// doc.dispathEvent(ev1);function handler1(e:MyEvent){ console.log(e + "----------------");}function handler2(e:MyEvent){ console.log(e + "||||||||||||||||||||"); (e.target as MyTarget).removeEventListener("zi",handler2);}效果:
第二次拋發(fā)的事件被刪除 到此,關(guān)于“TypeScript入門知識(shí)點(diǎn)有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
名稱欄目:TypeScript入門知識(shí)點(diǎn)有哪些
鏈接分享:http://weahome.cn/article/jihgsi.html