typescript入門和typescript面向?qū)ο笕腴T

前言

typescript(以下簡(jiǎn)稱ts)是微軟開發(fā)、google(Angular2)支持的 js超集(增加面向?qū)ο缶幊痰奶匦院湍承〦S6語法特性)渐裸,任何js都可以不經(jīng)修改的在ts環(huán)境下運(yùn)行。很多著名的項(xiàng)目都已經(jīng)將ts作為了開發(fā)語言装悲,例如昏鹃,我國(guó)的HTML5游戲引擎Egret、我國(guó)的前端樣式庫Ant-desgin等诀诊《床常總之,ts絕對(duì)代表了未來的大前端語言趨勢(shì)属瓣,不學(xué)就落后了载迄。

ts環(huán)境開發(fā)

一般情況下讯柔,可以在babel或者ts的在線練習(xí)環(huán)境來快速體驗(yàn)ts語言。但是护昧,為了做項(xiàng)目魂迄,還是需要在本地安裝好開發(fā)環(huán)境的,接下來捏卓,我們就看看如何在本地配置開發(fā)環(huán)境和IDE的极祸。

安裝compiler

npm i -g typescript
tsc --version
// 新建一個(gè)test.ts文件
export class testTS {

}
tsc test.ts --->編譯--->test.js

"use strict";
exports.__esModule = true;
var testTS = /** @class */ (function () {
    function testTS() {
    }
    return testTS;
}());
exports.testTS = testTS;

與vscode進(jìn)行集成

tsc --init // 創(chuàng)建tsconfig.json

有了tsconfig.json文件后,就可以對(duì)文件進(jìn)行配置怠晴,設(shè)置好js文件夾和ts文件夾。

編譯ts文件

使用vscode編譯ts文件非常的方便浴捆,只需要run task即可蒜田。

run task

run task后會(huì)出現(xiàn)tsc:build 、tsc:watch兩個(gè)選項(xiàng)选泻,tsc:build是快速編譯冲粤,tsc:watch是實(shí)時(shí)、監(jiān)控編譯页眯,編譯好后梯捕,文件就會(huì)存在于在tsconfig.json指定好的目錄下了。

前端工程比較龐大的時(shí)候窝撵,或者需要將多個(gè)ts輸出到多個(gè)js文件夾下的時(shí)候傀顾,建議使用webpack、gulp或者grunt來進(jìn)行項(xiàng)目的打包和編譯碌奉。這幾個(gè)工具都是前端工程化的工具短曾,在此不做一一展開來講了。

簡(jiǎn)單學(xué)學(xué)ts語法

ts語法很多也是es6語法赐劣,因此嫉拐,簡(jiǎn)單說說一些ts語法,全當(dāng)對(duì)es6進(jìn)行復(fù)習(xí)了魁兼。

字符串特性

多行字符串

使用``

字符串模板

使用`${xxx}`

自動(dòng)拆分字符串

下圖婉徘,test函數(shù)可以通過字符串模板來調(diào)用參數(shù),就是后邊的這些咐汞,可以用字符串模板調(diào)用盖呼,然后,自動(dòng)拆分


自動(dòng)拆分字符串之函數(shù)調(diào)用
自動(dòng)拆分字符串之結(jié)果展示

參數(shù)

指定參數(shù)類型

使用【冒號(hào) = :】來指定變量碉考、參數(shù)塌计、函數(shù)返回值類型,并且侯谁,類型具有推斷機(jī)制锌仅,如果給string類型的變量章钾,賦值數(shù)字的話,IDE會(huì)報(bào)錯(cuò)热芹。(這里也僅僅是IDE會(huì)報(bào)錯(cuò)贱傀,因此,js是動(dòng)態(tài)語言伊脓,不存在類型的概念府寒,通過ts轉(zhuǎn)換為js不管怎么說都是對(duì)的)

另外,通過類的概念自定類型后报腔,自定義的類型也可以作為普通類型使用

var nymm:string='11111dssasd'
var nymm:any='11111dssasd'
var nymm:number='11111dssasd'
var nymm:boolean='11111dssasd'

// 可選參數(shù)株搔,b就是可選參數(shù),可以不傳遞
function test(er:string,ki:string = "ddd",op?:string):void{

}

// 自定義類型

class Car {
    name:string;
    logo:string
}

var ben:Car = new Car();

默認(rèn)參數(shù)與可選參數(shù)

給參數(shù)賦默認(rèn)值纯蛾,如果有普通參數(shù)纤房,那么,默認(rèn)參數(shù)不可以為第一個(gè)參數(shù)翻诉,否則炮姨,在賦值的時(shí)候,會(huì)對(duì)參數(shù)的賦值進(jìn)行覆蓋碰煌。同時(shí)舒岸,還提供了【問號(hào) = ?】來指定其為可選參數(shù)芦圾,并且蛾派,可選參數(shù)必須放在必選參數(shù)之后。

function test(er:string,ki:string = "ddd",op?:string):void{

}

函數(shù)

Rest and Spread操作符

Rest and Spread操作符堕扶,例如【...args】碍脏,這個(gè)操作符表示可以聲明任意數(shù)量的方法參數(shù)。這個(gè)參數(shù)表示的是一個(gè)數(shù)組稍算,調(diào)用該參數(shù)的時(shí)候典尾,要按照數(shù)字的方式進(jìn)行處理。

// 任意長(zhǎng)度參數(shù)定義
function fun(...args){}

// 定長(zhǎng)參數(shù)定義
function fun2(a,b,c)
var ays = [1,2,9]

// 定長(zhǎng)函數(shù)調(diào)用
fun2(...ays)

generator和async函數(shù)操縱順序程序

generator以及async函數(shù)糊探,都是promise的語法糖钾埂。用來控制函數(shù)的執(zhí)行過程,通過yield和await來控制代碼的執(zhí)行科平。配合著next()褥紫,來控制順序程序的暫停和開啟。然后瞪慧,每次髓考,調(diào)用next(),都會(huì)停在某一個(gè)yield或者async弃酌。

圖片.png

對(duì)于異步函數(shù)氨菇,其實(shí)就是promise的返回儡炼,因此,直接操作返回的對(duì)象即可查蓉。

析構(gòu)表達(dá)式(destructuring)

通過表達(dá)式將對(duì)象或數(shù)組拆解成任意數(shù)量的變量

拆解對(duì)象

拆解對(duì)象

拆解數(shù)組

拆解數(shù)組跳過數(shù)據(jù)
拆解數(shù)組 + Rest and Spread操作符

箭頭表達(dá)式

用來聲明匿名函數(shù)乌询,消除傳統(tǒng)匿名函數(shù)的this指針問題,因?yàn)橥阊校琷s中的this關(guān)鍵字妹田,會(huì)發(fā)生js指向和預(yù)期指向不一致的情況。因?yàn)榫楣玻瑃his的指向是調(diào)用自己的函數(shù)的指向鬼佣,但是,因?yàn)殚]包霜浴、函數(shù)嵌套調(diào)用等原因沮趣,this的指向會(huì)發(fā)生改變。通過箭頭表達(dá)式坷随,將this指向了最外層的函數(shù),從而驻龟,讓一個(gè)函數(shù)內(nèi)共享了this內(nèi)存温眉,從而解決指向改變的問題。

最簡(jiǎn)單的匿名函數(shù)

var kill = (bill,kate)=>bill + kate;

等價(jià)于

var kill = function (bill,kate) {return bill + kate};

this指向發(fā)生改變的一種情況

例如翁狐,上圖的情況类溢,this指向了匿名函數(shù),因此會(huì)打印不出值露懒。

this指向發(fā)生改變的一種情況的實(shí)際數(shù)據(jù)打印

對(duì)于非箭頭函數(shù)表達(dá)式下的this的簡(jiǎn)單說明

在普通函數(shù)中闯冷,this指代的是調(diào)用他的函數(shù),例如

var obj = {
  foo: function () { console.log(this.bar) },
  bar: 1
};

var foo = obj.foo;
var bar = 2;

obj.foo() // 1
foo() // 2

這個(gè)函數(shù)打印的就不是一個(gè)值懈词,因?yàn)樯咭琭oo是引用,因此是全局環(huán)境下的對(duì)象對(duì)于this的調(diào)用坎弯,因此纺涤,值是不一樣的。

當(dāng)然抠忘,關(guān)于this撩炊,很有必要單獨(dú)開一個(gè)文章來講解

循環(huán)

本節(jié)將要講解forEach()、for in崎脉、for of循環(huán)的異同

forEach()

forEach()拧咳,有兩個(gè)特性,第一是不能break跳出囚灼,第二是會(huì)忽略對(duì)象的展示骆膝。

forEach()
忽略對(duì)象的展示

for in

for in循環(huán)的是keys祭衩,同時(shí)可以使用break跳出。

for of

for of循環(huán)的是values谭网,同時(shí)可以使用break跳出汪厨。

面向?qū)ο?/h1>

ts的面向?qū)ο螅蛘哒fjs的面向?qū)ο笈cc++或者java很不一樣愉择。因?yàn)檫@種解釋型的語言劫乱,本身就已經(jīng)是對(duì)象了,因此锥涕,在操縱內(nèi)存的時(shí)候要格外小心衷戈。

Class

ts要求使用面向?qū)ο蟮奶匦詠頃鴮懗绦颍热皇敲嫦驅(qū)ο蟛阕梗敲粗掣荆涂梢愿玫睦美^承、封裝和多態(tài)了破花。使用面向?qū)ο笄ぃ梢愿玫膶?shí)現(xiàn)抽象定義和整個(gè)程序的架構(gòu)。

定義

類的定義

我們可以看到es5下座每,類的定義是基于匿名函數(shù)和閉包的前鹅,同時(shí)還提供了prototype這個(gè)屬性。在此不做展開峭梳,大家自行查閱資料舰绘。(此處涉及到匿名函數(shù)的調(diào)用和原型鏈的知識(shí),此處建議學(xué)習(xí)v8引擎的相關(guān)說明資料https://v8.dev/docs和ECMAScript的說明文檔https://tc39.es/ecma262/#sec-ecmascript-specification-types

另外葱椭,對(duì)于上邊的代碼捂寿,特別要注意的是,在es5下孵运,匿名函數(shù)一定要自執(zhí)行后秦陋,才能調(diào)用,因?yàn)槠桑跊]有執(zhí)行前踱侣,匿名函數(shù)沒有意義。

訪問控制符

默認(rèn)的訪問控制符是public大磺,同時(shí)還可以添加private和protected抡句。public表示都可以訪問,private表示內(nèi)部訪問杠愧,protected表示內(nèi)部包或者子類可以訪問待榔。

構(gòu)造函數(shù)(constructor())

構(gòu)造函數(shù)

構(gòu)造函數(shù)的參數(shù),一定要顯式的做訪問控制符的聲明,否則需要在外部單獨(dú)指定其訪問控制權(quán)限锐锣。

繼承(extends和super)

如果我們用es5來實(shí)現(xiàn)class和extends語法糖的話腌闯,那么就應(yīng)該是這樣的幾個(gè)函數(shù),此處又涉及到多個(gè)問題雕憔,因此姿骏,之后會(huì)專門開個(gè)文章系列來討論這部分內(nèi)容。另外斤彼,通過查看es5的實(shí)現(xiàn)方式分瘦,我們也明白了,extends和super的意義琉苇。

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    }
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var Animal = /** @class */ (function () {
    function Animal(name) {
        this.name = name;
    }
    Animal.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 0; }
        console.log(this.name + " moved " + distanceInMeters + "m.");
    };
    return Animal;
}());
var Snake = /** @class */ (function (_super) {
    __extends(Snake, _super);
    function Snake(name) {
        return _super.call(this, name) || this;
    }
    Snake.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 5; }
        console.log("Slithering...");
        _super.prototype.move.call(this, distanceInMeters);
    };
    return Snake;
}(Animal));
var Horse = /** @class */ (function (_super) {
    __extends(Horse, _super);
    function Horse(name) {
        return _super.call(this, name) || this;
    }
    Horse.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 45; }
        console.log("Galloping...");
        _super.prototype.move.call(this, distanceInMeters);
    };
    return Horse;
}(Animal));
var sam = new Snake("Sammy the Python");
var tom = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);

泛型(generic)

參數(shù)化的類型嘲玫,一般用來限制集合的內(nèi)容。換句話說并扇,就是聲明某個(gè)集合必須是什么數(shù)據(jù)類型去团。

var workers:Array<Worker>  = []

這個(gè)數(shù)組就要求,我們只能將worker放到數(shù)組中穷蛹。

接口(interface)

用來建立某種代碼約定土陪,使得其他開發(fā)者在調(diào)用某個(gè)方法或者創(chuàng)建新的類時(shí)必須遵循接口所定義的代碼約定。使用interface定義肴熏,使用implements引用旺坠。

定義接口并使用

定義接口并使用

基于implements實(shí)現(xiàn)接口

基于implements實(shí)現(xiàn)接口

模塊(Module)

在ts或者js中,一個(gè)文件扮超,其實(shí)就是一個(gè)模塊,通過export和import進(jìn)行模塊的導(dǎo)出和導(dǎo)入蹋肮。

模塊可以幫助開發(fā)者將代碼分割為可重用的單元出刷。開發(fā)者可以自己決定將模塊中的哪些資源(類、方法坯辩、變量)暴露出去供外部使用馁龟,哪些資源只在模塊內(nèi)部使用。

值得注意的是漆魔,對(duì)于繼承來說坷檩,因?yàn)椋惪隙ㄒ彩窃诓煌K中的改抡,因此矢炼,我們既要將模塊import,還要extends對(duì)應(yīng)的類阿纤。(此處要注意CommonJS(CMD句灌、AMD)和es6模塊的異同)

注解(annotation)

注解為程序的元素(類、方法、變量)加上更加直觀的說明胰锌,這些說明信息與程序的業(yè)務(wù)邏輯無關(guān)骗绕,只是供指定的工具或者框架使用。(關(guān)于注解资昧,可以具體查看相關(guān)工具的文檔)

類型定義文件(*.d.ts)

ts想要使用js工具包已有的程序應(yīng)該怎么辦呢酬土?之前以及說過了,js可以不經(jīng)修改的在ts下執(zhí)行格带,那么撤缴,我們其實(shí)可以直接調(diào)用js,但是践惑,又存在語法差異腹泌,不免會(huì)產(chǎn)生bug,因此尔觉,使用類型定義文件來幫助ts調(diào)用js的已有代碼凉袱,放在bug的產(chǎn)生。例如:koa等

類型定義文件侦铜,來源于DefinitelyTyped項(xiàng)目https://github.com/DefinitelyTyped/DefinitelyTyped

例如koa的類型定義文件就是在這個(gè)下邊https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa/index.d.ts专甩,通過 npm i @types/koa便可以安裝這個(gè)項(xiàng)目,也可以通過typings來安裝和查找钉稍。這個(gè)項(xiàng)目中涤躲,有大量的已有js項(xiàng)目的類型定義文件。

注意贡未,其實(shí)還可以通過通過typings(https://github.com/typings/typings)來尋找以及存在的類型定義文件种樱。但是,由于官方推薦 NPM @types的形式來安裝類型定義文件俊卤,因此嫩挤,可以不去安裝typings了,直接使用npm的安裝方式即可消恍。

npm WARN deprecated typings@2.1.1: Typings is deprecated in favor of NPM @types -- see README for more information
npm WARN deprecated popsicle-proxy-agent@3.0.0: Use `agent` option with `popsicle` directly

npm i typings -g
typings search --name project_name
typings install project_name --save

后記

本文概要的講解了ts和ts的面向?qū)ο笃裾眩瑢?duì)于很多知識(shí)都沒有展開來講,例如狠怨,es5為什么要那樣構(gòu)建類约啊,class、extends等語法糖的es5版本為啥要那樣寫佣赖,注解如何使用等等恰矩。

對(duì)于此部分的內(nèi)容,我將會(huì)在后續(xù)的專題中憎蛤,深入討論的枢里。

討論一下ts做后端開發(fā)

對(duì)于使用過Java、PHP、C#等開發(fā)后端的程序員來說栏豺,ts語法會(huì)讓你們感到更加的親切彬碱。但是,因?yàn)榘峦荩瑃s本身還在發(fā)展巷疼,因此,例如裝飾器灵奖、注解等還是需要第三方庫進(jìn)行支持嚼沿。

Routing-controllers庫

https://github.com/typestack/routing-controllers

該庫為express、koa添加了裝飾器模式瓷患,可以通過注解的方式來操控web服務(wù)器骡尽。

TypeDI依賴注入庫

https://github.com/pleerock/typedi

TypeORM

https://github.com/typeorm/typeorm

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市擅编,隨后出現(xiàn)的幾起案子攀细,更是在濱河造成了極大的恐慌,老刑警劉巖爱态,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谭贪,死亡現(xiàn)場(chǎng)離奇詭異耳高,居然都是意外死亡排抬,警方通過查閱死者的電腦和手機(jī)哆键,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門凡傅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人挫望,你說我怎么就攤上這事驾锰“绫蹋” “怎么了磁椒?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵凑阶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我衷快,道長(zhǎng),這世上最難降的妖魔是什么姨俩? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任蘸拔,我火速辦了婚禮,結(jié)果婚禮上环葵,老公的妹妹穿的比我還像新娘调窍。我一直安慰自己,他們只是感情好张遭,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布邓萨。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缔恳。 梳的紋絲不亂的頭發(fā)上宝剖,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音歉甚,去河邊找鬼万细。 笑死,一個(gè)胖子當(dāng)著我的面吹牛纸泄,可吹牛的內(nèi)容都是我干的赖钞。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼聘裁,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼雪营!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起衡便,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤献起,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后砰诵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體征唬,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年茁彭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了总寒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡理肺,死狀恐怖摄闸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情妹萨,我是刑警寧澤年枕,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站乎完,受9級(jí)特大地震影響熏兄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜树姨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一摩桶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧帽揪,春花似錦硝清、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽士飒。三九已至,卻和暖如春蔗崎,著一層夾襖步出監(jiān)牢的瞬間酵幕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工蚁趁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裙盾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓他嫡,卻偏偏與公主長(zhǎng)得像番官,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子钢属,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容