文章來源于公眾號:小姐姐味道
前端那么多酷炫的東西,真是太好玩了。但是,JavaScript 是個攔路虎,尤其是熟悉了 Java 之類的強(qiáng)類型檢查語言之后,每次看到 JavaScript 都感覺不爽。作為一個后端,寫 JavaScript 真的是有一種寫吐了的感覺。萬幸現(xiàn)在有了更好的選擇。
為什么要學(xué)習(xí) TypeScript 呢?因?yàn)樗恼Z法和 Java 真的很像。有了這個東西,就可以擺脫惱人的 JavaScript ,擁抱前端的技術(shù)棧。
TypeScript
是JavaScript
的超集。意思就是在ts
中可以直接書寫js
。在我的第一感覺里,js
就像是編譯后的可執(zhí)行文件,而ts
就像是Java語言,或者Scala語言等。不過,這也只是類比而已,ts中的很多語法,其實(shí)大多數(shù)是編譯期用的,在真正的js
文件里,抹除了很多的信息。
如上圖, ts 文件通過 tsc 編譯器,生成普通的 js 文件。接下來,就可以使用 node 命令執(zhí)行這個普通的 js 文件。
下面是一段簡單的 ts 代碼。是不是和 Java 很像?
class Animal {
public name;
protected a;
private b: string;
constructor(name) {
this.name = name;
}
sayhi() {
return `my name is ${this.name}`;
}
}
class Cat extends Animal {
constructor(name) {
super(name)
}
sayhi() {
return "meow " + super.sayhi()
}
static iaAnimal(a) {
return a instanceof Animal;
}
}
function gen<T extends Animal>(name: T): void {
console.log(name.name)
}
下面簡單介紹一下一些基本的語法,當(dāng)然了,有些語法是ES6的,但我也把它揉在一塊了。
類型相關(guān)
由于js是一門弱類型的語言,有很多的運(yùn)行時轉(zhuǎn)換,就不能使用類似于 Java 一樣的強(qiáng)類型轉(zhuǎn)換方式,所以typescript
可以在編譯階段通過語言特性增強(qiáng)一些類型檢查的功能。而在運(yùn)行時,大多數(shù)根本就沒有這樣的判斷,所以ts更像是一個過程工具。
對于一門語言來說,肯定離不開基本數(shù)據(jù)類型和自定義類型。 ts 提供了一系列的關(guān)鍵字作為特殊類型代號,其他的都好說,唯一讓我有點(diǎn)興趣的是聯(lián)合類型
,這非常有趣的一個特性。
typeof
關(guān)鍵字用于判斷是否是某種類型string
表明是字符串類型,它不同于Java,首字母是小寫boolean
和Boolean
類型是不同的number
直接表示數(shù)字類型,沒有那么多麻煩的精度問題(0b、0O、0x指明進(jìn)度問題)any
是萬能類型,相當(dāng)于Java中的Object,全部是any相當(dāng)于是普通js。所以,如果你恨ts,就可以一路any到天明never
表示那些永不存在的值類型object
表示非原始類型,和Java中的不太一樣string | number
類似這樣的是聯(lián)合類型,這也是非常神奇的一點(diǎn)。這里只允許這兩種類型的轉(zhuǎn)換,并且能調(diào)用的方法,要取兩者交集` 之間的字符串可以使用類似shell的語法,做模版
${}`readonly
這竟然是個關(guān)鍵字,表明只讀屬性[propName: string]: any;
這一行代碼值得研究,但不推薦這么做number[]
數(shù)組和Java類似,不過這是聲明后置的語法,值使用[]聲明,而不是{}function
函數(shù)和javascript的沒什么區(qū)別,有兩種聲明方式。lambda對js來說肯定是強(qiáng)項(xiàng)=>
的語法也比較惡心人,和ES6聯(lián)合起來可以寫一大篇文章...rest
注意這個東西!類似Java中變參的意思as
是一個關(guān)鍵字,我們可以理解為Java的cast
,但它也僅僅是語法檢查而已,運(yùn)行時并無法控制。(window as any)
很酷,但容易出錯
聲明相關(guān)
let
用來聲明普通變量,作用域小,{}之內(nèi)var
作用域大,函數(shù)級別或全局const
只讀變量,是靜態(tài)的;readonly卻是動態(tài)的,只不過聲明后不能改而已declare var
聲明全局變量(.d.ts
后綴的文件,這是一種約定)declare function
聲明全局方法declare class
全局類declare enum
全局枚舉類型declare namespace
全局命名空間export
這個主要是用于npm的,后續(xù)可以使用import導(dǎo)入
那什么是declare呢?私以為這個類似于python中的__init__.py
文件,用于暴露一些接口和函數(shù),另外為代碼自動補(bǔ)全提供了基本數(shù)據(jù)。
兩個默認(rèn)的約定。配置了tsconfig.json
以后,可以直接執(zhí)行tsc命令進(jìn)行編譯。///
三斜杠指令,很丑。
關(guān)于Class
從Java過來的同學(xué),會發(fā)現(xiàn)這些概念和Java是類似的,不過ts的語法更加簡單。
get
set
竟然是關(guān)鍵字,后面可直接跟上函數(shù)??梢愿淖儗傩缘馁x值和讀取行為!static
、instanceof
、public
、protected
、private
這些也都是有的,真的感覺和寫Java沒什么兩樣constructor
默認(rèn)是構(gòu)造方法,不像是Java要和class的名詞一樣abstract
也有,表明子類必須實(shí)現(xiàn),沒什么兩樣- 關(guān)于類和接口的區(qū)別,我覺得熟悉java的,對ts來說就是透明的
- 范型在Java里,語法也是非常的變態(tài),因?yàn)槟愫芏鄷r候不知道要把
<>
放在什么地方。在ts中,一樣的難受。具體怎么熟悉,只有在實(shí)踐中磨練了
關(guān)于type、interface、class
interface
定義了接口,這里的接口有意思,可以聲明實(shí)體,但是必須全部賦值才行??梢酝ㄟ^在成員變量前面加?
的方式來表明非必須,但很丑;?
也可以定義函數(shù)的可選參數(shù),6的很type
和interface一樣,在編譯時,會被抹除。兩者語法有細(xì)微差別,同時type可以定義更多類型,比如基本類型、聯(lián)合類型、元組等class
可以在里面實(shí)現(xiàn)方法,有點(diǎn)Java的味道了,所以不會被編譯器抹除。javascript使用構(gòu)造函數(shù)模擬class。
開發(fā)工具
tsc是typescript的編譯器。如果編譯出錯,可以指定底層的語法特性。
tsc --target es6
建議配置在tsconfig.json
文件里,會被自動識別。
{
"compilerOptions": {
"module": "commonjs",
"outDir": "lib",
"declaration": true,
"target":"es6"
}
}
vscode,通過.d.ts
文件,可以做到自動補(bǔ)全和語法檢查。但針對于復(fù)雜的個性化配置,還是無法做到類似idea那樣智能的提示和配置。
由此造成的后果就是,手頭上必須有一份參考文檔,并對參考文檔的目錄和功能熟悉。在遇到相應(yīng)的配置參數(shù)時,不得不翻閱到相應(yīng)的地方,然后拷貝過來。這對于一個 javaer 來說,實(shí)在是太痛苦了。
以上就是W3Cschool編程獅
關(guān)于半天掌握TypeScript,感覺就像寫Java的相關(guān)介紹了,希望對大家有所幫助。