成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長(zhǎng)資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

一篇文章帶你TypeScript入門(mén)(整理總結(jié))

本篇文章給大家?guī)?lái)了關(guān)于TypeScript入門(mén)的相關(guān)知識(shí),希望對(duì)大家有幫助。

一篇文章帶你TypeScript入門(mén)(整理總結(jié))

前言

ts是什么?ts其實(shí)是TypeScript的一個(gè)簡(jiǎn)稱,就跟JavaScript簡(jiǎn)稱為js一樣,官方給的解釋是,ts它是js的超集,其實(shí)js的代碼本質(zhì)上都是ts編譯的,例如寫(xiě)一個(gè)js代碼 document.write() ,上面的提示就是ts,如圖:

一篇文章帶你TypeScript入門(mén)(整理總結(jié))
系統(tǒng)里面寫(xiě)的是ts代碼,所以ts是js的超集,是給js添加拓展功能的語(yǔ)言,這樣的語(yǔ)言曾經(jīng)還有一個(gè)叫as,但是這個(gè)語(yǔ)言已經(jīng)沒(méi)了,它其實(shí)就是flash語(yǔ)言。但我么開(kāi)發(fā)需要完善js的話,必須得有這樣的一個(gè)東西,所以微軟拿著這個(gè)as的語(yǔ)法開(kāi)發(fā)了ts這個(gè)語(yǔ)言,也就是說(shuō)as和ts的語(yǔ)法基本是一樣的,只不過(guò)ts是微軟開(kāi)發(fā)的,然后推廣的不錯(cuò),現(xiàn)在隨著我們編程越來(lái)越全民化,ts使用的也就越來(lái)越多,包括在找工作中,如果你的薪資是在12k以上的話,基本上都會(huì)問(wèn)你會(huì)不會(huì)ts,現(xiàn)在的編程很多情況下都是用到ts,因?yàn)樗芙ojs添加拓展功能,

比如:可以進(jìn)行各種各樣的模塊化開(kāi)發(fā),像之前提到的AMD,CMD開(kāi)發(fā),CommonJS,es6的模塊化規(guī)范。假設(shè)現(xiàn)在在客戶端開(kāi)發(fā),有沒(méi)有一種開(kāi)發(fā)場(chǎng)景,既可以用AMD,也可以用CMD,CommonJS,es6的,

答案是沒(méi)有,因?yàn)镃ommonJS是只能在nodejs中使用,es6的模塊化開(kāi)發(fā)只能在服務(wù)器中用,它們都是有各自限制的。

但是ts中,想用什么都可以,它是支持全場(chǎng)景的。ts它更像后端,他的語(yǔ)法跟java最相似,這樣有什么好處?大家知道js是弱類(lèi)型語(yǔ)言,比如一個(gè)變量先定義一個(gè)數(shù)字型,然后再重新賦值一個(gè)字符串型的,這樣的話這個(gè)變量的類(lèi)型就改變了,這種弱類(lèi)型開(kāi)發(fā)是對(duì)項(xiàng)目有一定的安全隱患的,

比如就用這個(gè)變量去做其他事情,它有可能變成其他類(lèi)型的數(shù)據(jù),所以對(duì)開(kāi)發(fā)來(lái)說(shuō)是有安全隱患的,所以必須得有ts來(lái)規(guī)范js開(kāi)發(fā),消除這個(gè)安全隱患,這就是為什么ts像java、#c這些后端語(yǔ)言,這些強(qiáng)類(lèi)型語(yǔ)言定義變量的時(shí)候,需要先聲明這些變量的類(lèi)型是什么,一旦定義這個(gè)變量的類(lèi)型后,后期是不允許修改類(lèi)型的,有了這樣的規(guī)范約束后,開(kāi)發(fā)就更加安全了。

現(xiàn)在ts使用的場(chǎng)景是非常廣泛:js的提示(編輯器內(nèi)置了規(guī)范語(yǔ)法的ts),主流框架vue,react在底層寫(xiě)框架的時(shí)候用的也是ts。

說(shuō)這么多,下面直接介紹ts,也就是TypeScript。


TypeScript

簡(jiǎn)介

ts是一個(gè)給js添加特性的擴(kuò)展語(yǔ)言。

  1. TypeScript是由微軟開(kāi)發(fā)的一款開(kāi)源的編程語(yǔ)言。
  2. TypeScript是JavaScript的超集,遵循最新的es6、es5規(guī)范。TypeScript擴(kuò)展了JavaScript的語(yǔ)法。
  3. TypeScript更像后端java、C#這樣的面向?qū)ο笳Z(yǔ)言,可以讓js開(kāi)發(fā)大型企業(yè)項(xiàng)目。
  4. 谷歌也在大力支持TypeScript的推廣,谷歌的angular2.x+就是基于TypeScript語(yǔ)法。
  5. 最新的vue、React也可以集成TypeScript。
  6. nodeJs礦建Nestjs、midway中用的就是TypeScript語(yǔ)法。

能給js增加的功能有

  • 類(lèi)型批注和編譯時(shí)類(lèi)型檢查
  • 類(lèi)型推斷
  • 類(lèi)型擦除
  • 接口
  • 枚舉
  • Mixin
  • 泛型編程
  • 名字空間
  • 元組
  • Await
  • 類(lèi)
  • 模塊
  • lambda 函數(shù)的箭頭語(yǔ)法
  • 可選參數(shù)以及默認(rèn)參數(shù)

js 是一個(gè)弱類(lèi)型的語(yǔ)言,但ts是強(qiáng)類(lèi)型的,語(yǔ)法很相像,但ts算是擴(kuò)展的js的語(yǔ)法,ts通過(guò)類(lèi)型注解,提供編譯js時(shí)的靜態(tài)類(lèi)型檢查。


編譯

ts無(wú)法直接運(yùn)行,所以只能編譯成js運(yùn)行。類(lèi)似sass用來(lái)編譯css,不能直接運(yùn)行。
編譯工具 – typescript

在全局任意位置下,先檢測(cè)是否安裝過(guò)ts

tsc --version

一篇文章帶你TypeScript入門(mén)(整理總結(jié))

npm install -g typescript

一篇文章帶你TypeScript入門(mén)(整理總結(jié))

檢測(cè)是否安裝成功:

tsc -v

ts文件的后綴是ts,編譯命令:

tsc 被編譯的文件

會(huì)在被編譯文件的同級(jí)目錄下生成一個(gè)同名的js文件。

生成自定義名稱路徑的文件:

tsc 被編譯的文件 --outFile 編譯后的文件路徑

初始化命令:

tsc --init

執(zhí)行初始化命令后,會(huì)生成一個(gè)tsconfig.json文件,如下:

一篇文章帶你TypeScript入門(mén)(整理總結(jié))

其中常用配置項(xiàng)說(shuō)明:

代表ts要轉(zhuǎn)換后js版本

"target": "es5"

如果ts是以模塊形式書(shū)寫(xiě)的,使用什么樣的模塊化規(guī)范,默認(rèn)是commonJS

"module": "amd"

配置輸出目錄,可自己設(shè)置

"outDir": "./"

一篇文章帶你TypeScript入門(mén)(整理總結(jié))

上面的配置項(xiàng)配置好以后,執(zhí)行監(jiān)視命令會(huì)自動(dòng)編譯:

tsc -w

使用amd規(guī)范的時(shí)候,需要將require.js文件拷貝到項(xiàng)目根目錄下,且需要一個(gè)出口文件:

<script src="require.js" data-main="main.js"></script>

將ts編譯成js,自動(dòng)生成目標(biāo)js文件

tsc 目標(biāo)js文件

一篇文章帶你TypeScript入門(mén)(整理總結(jié))

一篇文章帶你TypeScript入門(mén)(整理總結(jié))


ts基礎(chǔ)類(lèi)型

在定義變量的時(shí)候需要指定類(lèi)型,且定義好類(lèi)型以后就不能改變他的類(lèi)型了 – 強(qiáng)類(lèi)型。

數(shù)值型

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í)大寫(xiě)Number類(lèi)型可以賦值為數(shù)值對(duì)象類(lèi)型 num = new Number(10);

布爾值

let isDone: boolean = false;let bool: Boolean = true; // 首字母大寫(xiě)的類(lèi)型可以賦值為對(duì)象類(lèi)型

boolean這種類(lèi)型只能賦值兩個(gè)值:true/false

var bool: boolean = true  var bool: boolean = new Boolean(true)

Boolean這種類(lèi)型除了上面的字面量方式的兩個(gè)值,還可以使用構(gòu)造函數(shù)方式

var bool: Boolean = false;var bool: Boolean = new Boolean(true)

字符串

var str: string = 'asdfasdf';var str1: String = new String('43563456')

數(shù)組

ts寫(xiě)的數(shù)組,其中的數(shù)據(jù)必須是同一個(gè)類(lèi)型,但不指定長(zhǎng)度
數(shù)組中所有數(shù)據(jù)的值類(lèi)型必須是數(shù)字

var arr: number[] = [1,2,3];var arr: Array<string> = ['a','b'];

聲明二維數(shù)組

var arr: number[]var brr: number[][] = [     [1,2,3],     [4,5,6]];

元組 Tuple

ts中的元組表示不同類(lèi)型數(shù)據(jù)組成的集合,通常會(huì)固定長(zhǎng)度,同樣可以使用下標(biāo)訪問(wèn)元素和給元素賦值

元組中就可以放不同類(lèi)型的數(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的類(lèi)型,其他類(lèi)型不允許

x.push('aaaa')

錯(cuò)誤

 x.push(true) // 錯(cuò)誤

當(dāng)給元組中并不存在的下標(biāo)進(jìn)行賦值的時(shí)候,會(huì)使用聯(lián)合類(lèi)型:

x[3] = 'world'; // OK, 字符串可以賦值給(string | number)類(lèi)型x 6] = true;// Error, 布爾不是(string | number)類(lèi)型

枚舉

ts中的枚舉相當(dāng)于在定義變量類(lèi)型,這個(gè)類(lèi)型有固定的取值范圍,默認(rèn)值從0開(kāi)始,向后遞增,使用指定的鍵來(lái)?yè)Q換取到值,如果一個(gè)變量使用了這個(gè)類(lèi)型,那他的值就必須從這個(gè)類(lèi)型中選擇,不能隨便賦值:

枚舉 – 必須使用指定的集合中的值
枚舉類(lèi)型,其實(shí)是給數(shù)字起了一些名字,讓我們可以通過(guò)這個(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; // 不男不女

通過(guò)對(duì)應(yīng)值的數(shù)字獲取到對(duì)應(yīng)的名字 – 名字是字符串類(lèi)型

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

Any類(lèi)型,表示弱類(lèi)型,也就是當(dāng)我們定義一個(gè)變量的時(shí)候,不能確定變量值的類(lèi)型的時(shí)候,這個(gè)類(lèi)型我們又愛(ài)又恨
使用:

var a:any = 20var b:any = 'asdfasdf'var c:any = [1,2,3]

注意:本來(lái)我們使用ts編寫(xiě)代碼,為的是限制類(lèi)型,減少安全隱患,但是如果使用了any類(lèi)型,就跟直接寫(xiě)js一樣了,失去了意義,所以若非迫不得已,盡量不要使用。

Void

這種類(lèi)型,一般用于函數(shù)執(zhí)行后,不使用return返回結(jié)果的時(shí)候,就指定返回結(jié)果是void
聲明變量的時(shí)候不使用它 – 當(dāng)函數(shù)沒(méi)有返回值的時(shí)候,返回類(lèi)型指定為void

function fn(a:number,b:number):void{    console.log(a*b);}

Undefined

這種類(lèi)型主要用于參數(shù)和返回值,用于變量毫無(wú)意義,因?yàn)槎x一個(gè)變量指定為undefined類(lèi)型時(shí),以后也就只能是undefined類(lèi)型了,函數(shù)中的用法:

function fn(num:number|undefined):number|undefined{     return num;}

undefined – 未定義類(lèi)型

var a:undefined = undefined

定義變量不用undefined,因?yàn)槎x了沒(méi)有用

通常會(huì)用在函數(shù)的參數(shù)里面
希望fn函數(shù)的參數(shù)a是可選項(xiàng)

function fn(a:number|undefined):void{     console.log(a);}fn(undefined)

函數(shù)可選項(xiàng)
參數(shù)名后面,類(lèi)型的冒號(hào)之前加 ? 表示這個(gè)參數(shù)是可選項(xiàng)
undefined通常用在函數(shù)返回值,如果返回的是undefined就需要在返回值的地方指定undefined類(lèi)型

function fn(a?:number):number|undefined{     return a;}fn()

Null

null類(lèi)型 – 空 – 這個(gè)數(shù)據(jù)要被銷(xiāo)毀啦
通常在定義復(fù)雜數(shù)據(jù)類(lèi)型,且在后期需要給賦值為null的時(shí)候使用

var a:number|null = 10;

使用變量a計(jì)算 – 完成

讓內(nèi)存回收這個(gè)變量

a = null

Never

never類(lèi)型表示永遠(yuǎn)不存在的值的類(lèi)型,例如,一個(gè)函數(shù)中拋出的錯(cuò)誤,函數(shù)中有死循環(huán)永遠(yuǎn)不可能返回 …

function fn():never{     throw new Error('錯(cuò)誤')}function fn():never{     return fn()}fn()

Object

對(duì)象類(lèi)型:

var obj: object = {     name:"張三"}

錯(cuò)誤寫(xiě)法 - 對(duì)象默認(rèn)不允許添加鍵值對(duì)

obj.name = '張三';

類(lèi)型斷言

如果在一段代碼執(zhí)行后的類(lèi)型種類(lèi)的可能性比較多,就需要假設(shè)這是一種什么類(lèi)型 – 這種操作就叫做斷言。

如果一個(gè)表達(dá)式的結(jié)果有可能是多種類(lèi)型,最終需要肯定其中一種

var abcd: any = [1, 2, 3, 4, 5];

斷言abcd變量是一個(gè)數(shù)組

(abcd as [string,number]).push(6)(abcd as string) += 'ddd'

函數(shù)聲明

在ts中,函數(shù)定義比起js中,多了參數(shù)類(lèi)型和返回值的類(lèi)型定義:
函數(shù)的定義,參數(shù)的類(lèi)型聲明,返回值的類(lèi)型聲明

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í)候,寫(xiě)法稍有不同:
參數(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ù)的最后面

展開(kāi)運(yùn)算符和合并運(yùn)算符同樣可以使用在ts中,但是要注意運(yùn)算符后面的變量的類(lèi)型設(shè)置。

計(jì)算不定實(shí)參的和

function  sum(...arr:Array<number>){     var sum = 0;     for(var i=0;i<arr.length;i++){         sum += arr[i]     }     return sum;}var res = sum(1,2,3);console.log(res);

函數(shù)重載:通過(guò) 為同一個(gè)函數(shù)提供多個(gè)函數(shù)類(lèi)型定義 來(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)非常類(lèi)似,可以聲明一個(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中的類(lèi)

定義

定義方式跟es6的定義方式類(lèi)似

class 類(lèi)名{     constructor(){      }}
class Person{     // 靜態(tài)屬性 - 用類(lèi)名直接調(diào)用的屬性     static weight:number;      // 類(lèi)的屬性要定義在這里     name:string; // 表示類(lèi)中有一個(gè)屬性叫name     // 在ts類(lèi)中,屬性和方法前面可以加一個(gè)修飾符:     /*         public - 公開(kāi)的 - 在哪里都能用         protected - 受保護(hù)的         private - 私有的     */     public age:number; // public可以省略的     protected sex:string; // 受保護(hù)的只能在類(lèi)里面用,類(lèi)的外面不能用的     private height:number; // 私有的只能在類(lèi)里面使用,類(lèi)外面不能用     constructor(name:string,age:number,sex:string,height:number,weight:number){         // 給屬性賦值的時(shí)候,必須在這個(gè)類(lèi)中是本來(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ù)的屬性不能類(lèi)的外面使用 // console.log(p.height) // 私有屬性不能類(lèi)的外面使用   // p.init()  console.log(Person.weight); Person.fly()

繼承

ts中類(lèi)的繼承和es6的繼承是一樣,使用extends關(guān)鍵字,然后在構(gòu)造函數(shù)中調(diào)用super函數(shù)相當(dāng)于在調(diào)用父類(lèi)的構(gòu)造函數(shù)。

如果子類(lèi)和父類(lèi)有同名的方法,在子類(lèi)調(diào)用這個(gè)方法的時(shí)候先在子類(lèi)里面找,如果子類(lèi)沒(méi)有再到父類(lèi)里面找。

class Person{     // 靜態(tài)屬性 - 用類(lèi)名直接調(diào)用的屬性     static weight:number;      // 類(lèi)的屬性要定義在這里     name:string; // 表示類(lèi)中有一個(gè)屬性叫name     // 在ts類(lèi)中,屬性和方法前面可以加一個(gè)修飾符:     /*         public - 公開(kāi)的 - 在哪里都能用         protected - 受保護(hù)的         private - 私有的     */     public age:number; // public可以省略的     protected sex:string; // 受保護(hù)的只能在類(lèi)里面用,類(lèi)的外面不能用的     private height:number; // 私有的只能在類(lèi)里面使用,類(lèi)外面不能用     constructor(name:string,age:number,sex:string,height:number,weight:number){         // 給屬性賦值的時(shí)候,必須在這個(gè)類(lèi)中是本來(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ù)的屬性不能類(lèi)的外面使用 // console.log(p.height) // 私有屬性不能類(lèi)的外面使用   // p.init()  console.log(Person.weight); Person.fly()

類(lèi)的修飾符

在類(lèi)中定義屬性的時(shí)候,提供了3個(gè)修飾符:

  1. public:公有的 – 在類(lèi)里面、子類(lèi)中、類(lèi)的外面都可以訪問(wèn)
  2. protected:受保護(hù)的 – 在類(lèi)里面、子類(lèi)中可以訪問(wèn),在類(lèi)外面不能訪問(wèn)
  3. private:私有的 – 在類(lèi)里面可以訪問(wèn),在子類(lèi)和類(lèi)的外面都不能訪問(wèn)

靜態(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ú)法訪問(wèn)到普通的屬性,只能訪問(wèn)到靜態(tài)的屬性。

class Person{     public name:string = "張三"; 	static age:number = 20;     constuctor(){      }     static print1(){         console.log(this.name); // 訪問(wèn)不到     } 	static print2(){         console.log(Person.name); // 可以訪問(wèn)到     }}Person.print1();Person.print2();

屬性可以設(shè)置為只讀

多態(tài)

面向?qū)ο蟮娜筇攸c(diǎn):封裝、繼承、多態(tài)

含義:多態(tài)就是說(shuō),父類(lèi)定義一個(gè)方法不去實(shí)現(xiàn),讓繼承它的子類(lèi)去實(shí)現(xiàn),這樣每個(gè)子類(lèi)都會(huì)有不同表現(xiàn)。多態(tài)其實(shí)也是繼承的一種表現(xiàn)。

// 父類(lèi) - 動(dòng)物類(lèi)class Animal{     public tui:string = "有腿";     public eat(){         console.log("喜歡吃");     }     public sport(){         console.log("能走");     }     public tuiNum(){         console.log("有多條腿");     }}// 子類(lèi) - 人類(lèi)class Person extends Animal{     sport(){         console.log("直立走");     }     tuiNum(){         console.log("兩條腿");     }}var p = new Person();console.log(p.tui); // 有腿p.eat(); // 喜歡吃p.sport(); // 直立走p.tuiNum() // 兩條腿// 子類(lèi) - 鳥(niǎo)類(lèi)class Bird extends Animal{     sport(){         console.log("很少走,通常都在飛");     }     tuiNum(){         console.log("兩條腿");     }}var b = new Bird();console.log(b.tui);b.eat();b.sport(); // 很少走,通常都在飛b.tuiNum(); // 兩條腿// 子類(lèi) - 狗類(lèi)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)
一篇文章帶你TypeScript入門(mén)(整理總結(jié))

**小總結(jié):**多態(tài)就是多個(gè)子類(lèi)繼承自同一個(gè)父類(lèi),但是每個(gè)子類(lèi)將繼承下來(lái)的屬性或方法做了改善,最終每個(gè)子類(lèi)表現(xiàn)出來(lái)的結(jié)果是不一樣的。

多態(tài)其實(shí)源于繼承,也是方法的重載。

抽象類(lèi)

在實(shí)際工作中,項(xiàng)目負(fù)責(zé)人通常會(huì)寫(xiě)一些標(biāo)準(zhǔn)(類(lèi)似于大綱),然后將標(biāo)準(zhǔn)交給具體實(shí)現(xiàn)的攻城獅,由攻城獅將這個(gè)標(biāo)準(zhǔn)進(jìn)行具體化開(kāi)發(fā)。

ts中的抽象類(lèi)就是為制作標(biāo)準(zhǔn)的。抽象類(lèi)不能被實(shí)例化,只能被派生類(lèi)繼承并實(shí)現(xiàn)。

定義抽象類(lèi)使用abstract關(guān)鍵字來(lái)修飾類(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)沒(méi)有意義。跟普通的繼承是一樣的,并不能體現(xiàn)出標(biāo)準(zhǔn)的特殊。在抽象類(lèi)中通常會(huì)有抽象方法 – 使用abstract修飾的方法。

抽象方法必須在抽象類(lèi)中,且只需要定義方法結(jié)構(gòu),不要具體的實(shí)現(xiàn)。但是派生類(lèi)中必須實(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ī)定子類(lèi)必須包含eat方法。

抽象方法只能放在抽象類(lèi)中。

抽象類(lèi)存在的意義就是被其他類(lèi)繼承,是其他類(lèi)的基類(lèi)。

接口

抽象類(lèi)只能給方法定義標(biāo)準(zhǔn),對(duì)于屬性限制不夠,所以ts設(shè)計(jì)了接口語(yǔ)法,它定義了屬性和方法的規(guī)范,起到限制和規(guī)范的作用。接口并不關(guān)心這些類(lèi)的內(nèi)部狀態(tài)數(shù)據(jù),也不關(guān)心這些類(lèi)里方法的實(shí)現(xiàn)細(xì)節(jié),它只規(guī)定這批類(lèi)里必須提供某些方法,提供這些方法的類(lèi)就可以滿足實(shí)際需要。

ts的接口跟別的主流服務(wù)器端語(yǔ)言的接口一樣,同時(shí)還增加了更加靈活的接口類(lèi)型,包括屬性、函數(shù)、可索引和類(lèi)等。

簡(jiǎn)單來(lái)說(shuō),接口也是在定義標(biāo)準(zhǔn),只不過(guò)更加靈活和全面。

屬性接口

屬性接口專(zhuān)門(mén)為了約束屬性而設(shè)計(jì)。

語(yǔ)法:

interface 接口名稱{     變量:類(lèi)型;     變量:類(lèi)型;}

使用方式:

function printInfo(info:接口名稱){     console.log(info.屬性名); // 屬性名必須是接口定義過(guò)的,否則報(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è)鍵做限制,要做批量限制很麻煩,要寫(xiě)很多函數(shù)// 使用接口限制// 1.定義接口interface info {     name:string;     sex:string;}// 2.定義函數(shù)使用接口類(lèi)型function printInfo(data:info){     console.log(data.name);     console.log(data.sex);     // console.log(data.age); // 錯(cuò)誤 - info中沒(méi)有age鍵}// 3.使用printInfo({     name:"張三",     sex:"男",     age:20 // 錯(cuò)誤 - info中沒(méi)有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;}// 使用接口類(lèi)型封裝ajaxfunction sendAjax(config:Config){     var xhr = new XMLHttpRequest();     }// 調(diào)用sendAjax({     url:"",     });

函數(shù)接口

函數(shù)接口是專(zhuān)門(mén)為了約束函數(shù)的參數(shù)和返回而設(shè)計(jì)。

語(yǔ)法:

interface 接口名稱{     (參數(shù):類(lèi)型):返回值類(lèi)型}

例:

// 加密的接口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ù)類(lèi)型,同時(shí)也能支持未來(lái)的數(shù)據(jù)類(lèi)型,這在創(chuàng)建大型系統(tǒng)時(shí)為你提供了十分靈活的功能。

通俗理解:泛型就是解決 類(lèi) 接口 方法的復(fù)用性、以及對(duì)不特定數(shù)據(jù)類(lèi)型的支持(類(lèi)型校驗(yàn))

泛型方法:

function getInfo<T>(value:T):T{     return value;}getInfo<number>(123);getInfo<string>('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<T>(a:T):T{     return a;}fn<number>(234);fn<string>("abc");

命名空間

多人合作開(kāi)發(fā)項(xiàng)目的時(shí)候,避免不了會(huì)有函數(shù)、變量、類(lèi)等數(shù)據(jù)的命名沖突。但是ts不允許出現(xiàn)同名的類(lèi)、函數(shù)、變量(const定義的),這時(shí)候就需要使用命名空間來(lái)解決這個(gè)問(wèn)題。

命名空間其實(shí)就單獨(dú)做一個(gè)作用域,在當(dāng)前命名空間下的數(shù)據(jù)跟別的命名空間下的數(shù)據(jù)重名也不會(huì)產(chǎn)生沖突。

命名空間語(yǔ)法:

namespace A{ // namespace 命名空間名稱{}      class Animal{         constructor(){             console.log("A命名空間下的動(dòng)物類(lèi)");         }     }}// 使用動(dòng)物類(lèi)的時(shí)候A.Animal()

例:
命名空間

工作中一個(gè)項(xiàng)目都是協(xié)作開(kāi)發(fā),每個(gè)人負(fù)責(zé)一個(gè)文件,避免不了函數(shù)、變量、類(lèi)、接口會(huì)重名。
但是在ts文件,不允許類(lèi)、函數(shù)、let、const 重名
命名空間就是解決這個(gè)問(wèn)題的。
命名空間:就是開(kāi)辟自己的作用域

// 定義命名空間: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類(lèi) // 使用命名空間:命名空間.數(shù)據(jù) var a = new A.Animal("張三"); console.log(a.name); // 張三  var b = new B.Animal(20); console.log(b.age); // 20

從結(jié)果中可以看到,同名的類(lèi)處在不同的命名空間下是不會(huì)沖突的。

此時(shí),A命名空間就是一個(gè)單獨(dú)的模塊,進(jìn)行模塊化開(kāi)發(fā)的時(shí)候,需要將命名空間導(dǎo)出,也就是說(shuō)一個(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)前文件,接收命名空間,通過(guò)命名空間來(lái)調(diào)用數(shù)據(jù):

// 導(dǎo)入import { A } from "./demo"; // 導(dǎo)入的是一個(gè)命名空間var a = new A.Animal("張三"); // 實(shí)例化那個(gè)Animal

ts事件封裝

為什么要封裝?

因?yàn)樵趀s5和es6中允許dom元素繼承EventTarget,但是在ts中不允許繼承。

所以需要重構(gòu)EventTarget。

使用dispathEvent來(lái)拋發(fā)事件,需要使用Event。所以重構(gòu)Event。

本質(zhì):觀察者模式。

ts開(kāi)發(fā)的規(guī)則

開(kāi)發(fā)的時(shí)候通常都是在使用模塊化開(kāi)發(fā)

怎么進(jìn)行模塊化開(kāi)發(fā)?一個(gè)模塊一個(gè)類(lèi),通常類(lèi)的首字母會(huì)大寫(xiě),文件名稱和類(lèi)的名稱保持一致。

封裝

準(zhǔn)備工作:

將ts配置文件中的module選項(xiàng)改成amd。

 "module": "amd",

更改輸入輸出目錄:

"outDir": "./js", "rootDir": "./ts",

新建html,導(dǎo)入amd所使用的require.js。

配置導(dǎo)入文件以及異步推遲加載。

<script src="./require.js" data-main="./dist/Main"></script>

新建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<list.length;i++){             list[i].call(this,evt);         }         return true;     }}

新建IListener.ts文件

export default interface IListener{     [key:string]:Array<Function>;}

在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ā)的事件被刪除
一篇文章帶你TypeScript入門(mén)(整理總結(jié))

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
久久久精品国产SM最大网站| 精品无码中文字幕不卡| 国语第一次处破女| 精品无码人妻一区二区三区不卡| 久久亚洲日韩成人无码| 免费人成年激情视频在线观看| 女人夜夜春高潮爽A∨片传媒| 强开小婷嫩苞又嫩又紧视频| 色妞WW精品视频7777| 无码人妻熟妇av又粗又大| 亚洲AV中文无码乱人伦下载| 野兽的夜晚第四季忘不掉的前任 | ぱらだいす天堂中文网WWW| 得到超级肉禽系统的小说怎么办 | 99久久人妻精品免费二区| 成人福利国产午夜AV免费不卡在| 国产精品美女久久久| 久久99精品国产麻豆宅宅| 女的把腿张开男的往里面插| 色噜噜狠狠色综合成人网| 亚洲AV无码秘 蜜桃牛牛| 夜夜添夜夜添夜夜摸夜夜摸| WINDOWS乱码的乱码大全| 国产成人啪精品视频免费网站软件 | 99精品国产在热久久婷婷| 第一次爱的人视频播放完整版| 国产一起色一起爱| 麻花豆传媒剧国产MV免费天美| 日本人真人姓交大视频| 亚洲AV成人无码久久WWW| 中文字幕V亚洲ⅤV天堂| 高H禁伦餐桌上的肉伦| 精品人妻伦一二三区久久| 欧美成人片一区二区三区| 天天躁夜夜躁天干天干2020| 亚洲熟妇A∨日韩熟妇在线| 啊灬啊灬啊灬快灬高潮了I| 国产三级久久精品三级| 蜜臀AV在线无码国产| 熟女无套高潮内谢吼叫免费| 亚洲综合成人AⅤ在线网站| 成人精品视频一区二区三区尤物 | 国产丰满大屁股XXXX| 久久久久无码精品国产AV蜜桃1| 日本三级香港三级人妇99| 亚洲精品乱码久久久久久自慰 | 99精品人妻少妇一区二区| 国产精品视频第一区二区三区| 麻豆国产成人AV高清在线观看 | 国产SM调教视频在线观看| 旧芭乐视频官网下载地址IOS| 色婷婷亚洲六月婷婷中文字幕| 亚洲五月丁香综合视频| 大又大粗又爽又黄少妇毛片 | 丰满人妻中文字幕| 无遮挡边摸边吃奶边做视频免费 | 舌头伸进去添的我好爽高潮欧美| 亚洲色欲色欲色欲WWW| 粗了大了 整进去好爽视频| 精品一区二区久久久久久久网站| 日本熟少妇裸交ⅩXX视频| 亚洲熟妇AV不卡一区二区三区| 成色好的Y31S标准版| 久久午夜羞羞影院免费观看| 熟妇高潮精品区一区二区三| 在线观看的AV网站| 国产乱人伦偷精品视频不卡 | 久久国产午夜精品理论片34页| 少妇被粗大的猛进出69影院| 在线天堂中文最新版WWW| 国产无套无码AⅤ在线观看 | 亚洲成AV成人片在线观看| 成年免费视频黄网站在线观看| 久久免费的精品国产V∧| 无码精品人妻一区二区三区在线 | ZOOM动物高清视频| 久久国产精品亚洲艾草网| 调教后把奶头拴在跑步机上虐| BBBBBB嫩BBBBBB| 久久久久99精品国产片| 小东西好几天没弄了还能吃吗| 伴郎粗大的内捧猛烈进出视频观看| 久久久久久精品免费免费69| 小妖精又紧又湿高潮H视频69| 被黑人巨茎日出白浆的少妇| 浪货两个都满足不了你J视频| 亚洲AⅤ精品无码一区二区| 成人性欧美丨区二区三区| 免费无码作爱视频| 亚洲性无码AV在线| 国产无遮挡又黄又大又爽| 色婷婷综合激情综在线播放| 99热精国产这里只有精品| 久久久久亚洲精品天堂| 亚洲AV无码一区二区三区在线播 | 被吊起来张开腿供人玩弄 | 成人观看免费毛片爽| 能让我流水水的一千字| 一本大道色卡1卡2卡3乱码| 国产在线观看无码免费视频| 天堂AV无码AV在线A√| 白嫩少妇激情无码| 欧美性VIDEOS高清精品| 在线无码一区二区| 久久久久国色AV免费观看| 亚洲成在人线AⅤ中文字幕| 国产女人18毛片水真多1| 天天爽夜夜爽人人爽| 丰满人妻一区二区三区免费视频| 人人人爽人人澡人人高潮| GAY国产GV又粗又长又大| 男人忍不住挺进去了怎么回事| 一面亲上边一面膜下边的免费| 精品国产一区二区三区色欲| 亚洲AⅤ中文无码字幕色 | 无码人妻精品一区二区蜜桃视频| 粉嫩粉嫩一区性色AV片| 日韩综合亚洲色在线影院| 波多野结衣AV一区二区全免费观看 | 亚洲Aⅴ无码专区在线观看q | 性色AV一区二区三区| 国产成人精品亚洲午夜麻豆| 少妇内射兰兰久久| 国产99久久久国产精品~~牛| 少妇被三个黑人调教| 福利一区福利二区| 四虎在线观看视频9E9| 国产成人啪精品视频网站午夜| 乌克兰ZOOMKOOL| 国产精品无码午夜免费影院| 午夜影视啪啪免费体验区入口| 国产特级毛片AAAAAA高清| 亚洲AV无码一区二区三区人区 | 欧美一区二区三区性视频野战 | 欧美黑人疯狂性受XXXXX喷水| 91人人妻人人澡人人爽超污| 女人呻吟声大了男人越有劲吗| 91人人妻人人澡人人爽精品| 欧美日韩一区二区三区精品视频 | 人人妻人人澡人人爽超污| 成年无码AV片在线免缓冲| 少妇被三个黑人调教| 国产精品国产三级国产AV浪潮| 午夜无遮挡男女啪啪免费软件| 国产做无码视频在线观看浪潮| 亚洲成AV不卡无码无码不卡| 久久97超碰色中文字幕蜜芽| 一二三四在线视频社区3| 内地性生生活影视大全| Xx性欧美肥妇精品久久久久久久久 | AV无码一区二区三区| 日本理论片YY4800免费| 国产SUV精品一区二区五 | 2018一本久道在线线观看| 人妻出差精油按摩被中出| 东京热无码AV男人的天堂| 无人区一码一码二码三码区别 | 趴下老子要从后面CAO你| 东北往事之黑道风云20年第二部 | 中国亚州女人69内射少妇| 欧美日韩无套内射另类| 丰满人妻妇伦又伦精品App抖| 无码视频一区二区| 精品国产乱子伦一区二区三区| 在公车上露出奶头自慰| 人人妻人人狠人人爽| 国产精品美女久久久久久| 亚洲欧美日韩中文字幕一区二区三 | 少妇性生生活视频在线观看| 国产午夜无码片在线观看影院| 一本无码人妻在中文字幕| 欧美成人伊人久久综合网| 粉嫩AV一区二区夜夜嗨| 亚洲AV中文无码字幕色| 蜜臀av免费一区二区三区观看| 波多野结系列18部无码观看A | 少妇ⅩXXOOOZZXXHD| 红桃视频成人传媒| 50妺妺窝人体色www合集| 少妇人妻一级AV片| 精品人妻一区二区三区免费 | 一本一本大道香蕉久在线精品 | 久久精品人妻一区二区三区av| A阿V天堂亚洲阿∨天堂在线| 天天爽天天狠久久久综合麻豆| 久草日B视频一二三区| CHINESE国产XXXX实拍| 无遮挡裸体免费视频尤物| 老熟妇午夜毛片一区二区三区| 成人毛片女18免费| 亚洲卡5卡6卡7卡2021入口| 欧洲熟妇色XXXXX欧美老妇伦| 国产蜜臀AV无码一区二区三区| 在线播放国产精品三级| 色综合天天综合网国产| 久久精品国产亚洲AV麻| 成人永久免费高清视频在线观看| 亚洲精品无码久久毛片波多野吉衣| 屁屁草草影院CCYYCOM| 好男人好资源神马在线观看|