記錄下學習typescript的小結,也算是嘗試着本身寫些東西,從一個前端開發的角度去看待typescript這個新生物(2020年了,它不新了,是個老東西了,嘿嘿)。javascript
首先說說typescript是個什麼東西,哦,它不是個東西,它是一種基於js的擴展語言,更強調數據的類型,在我看來更像一個工具,一個規範前端代碼,讓前端也可以清晰的表達出面向對象這種思想的一個工具,關於具體是什麼參考某教程網站以下。html
TypeScript是JavaScript的一個超集,支持ECMAScript 6標準。前端
TypeScript由微軟開發的自由和開源的編程語言。java
TypeScript設計目標是開發大型應用,它能夠編譯成純JavaScript,編譯出來的JavaScript能夠運行在任何瀏覽器上。es6
嗯。。超集,就像下圖這樣,能夠理解爲typescript是js的一種衍生,包含了原來js的全部,還增長了一些新的屬性及場景。typescript
至於微軟開發的,沒啥好說的,能夠編譯成JavaScript,這點要說明一下,typescript是沒法在瀏覽器上直接運行的,因此須要藉助它自帶的工具將其編譯成JavaScript,而後再運行,這也是我所理解的工具語言。npm
任何事物的產生及存在都有其道理,那麼typescript產生的緣由的,先看看官網上的兩句英文簡介編程
TypeScript speeds up your development experience by catching errors and providing fixes before you even run your code.後端
蹩腳的英語水平翻譯下,簡單來講,TypeScript 能夠提升你的開發速度(確定不少剛開始使用的童鞋要說了,明明是降速,加了那麼多類型校驗),它是怎麼加速的呢,經過在你運行你的代碼以前就發現錯誤並提醒你(好傢伙,防患於未然,強!)數組
Types provide a way to describe the shape of an object, providing better documentation, and allowing TypeScript to validate that your code is working correctly.
再譯,類型提供了一種方法來描述對象的形態,提供更好的文檔,並容許TypeScript驗證代碼是否正常工做。
經過把類型的概念再詳細的描述,來更好的體現對象在js中的形態,不少前端開發,像我,對對象這個概念都是比較模糊的(不管是代碼仍是現實中,流下了單身狗的熱淚),如何作的,後面章節再細說。validate 這點多是typescript的初衷吧,因爲js是一門弱語言,對類型沒有特變關注,控制檯作下小實驗:
能夠看到js的世界,就算道(類型)不一樣,也能夠一塊兒爲謀,這像一種包容性,包容了本該出錯的一面,可是終究是錯誤,一個bug可能也會所以而起, typescript的出現某總意義上就是爲了解決這個不上不下的類型問題。
固然typescript的寫法上更趨向於java,對後端開發非常友好,更趨向於面向對象的編程,增長了代碼的可讀性,以及可維護性,這些能夠說是typescript產生的緣由。
那麼ts(簡寫了,後面同)是如何作的呢,各類官網教程上也都有,簡單來講就是使用ts的語法,編寫.ts後綴的文件,而後經過ts編譯器器或者Babel將ts文件編譯成js,而後就可使用了。
step:1
npm install -g typescript
step:2
編寫greeter.ts 指定入參person爲string類型
function greeter(person: string) {
return "Hello, " + person;
}
let user = 1; //這裏使用錯誤的例子
document.body.textContent = greeter(user);複製代碼
step:3
tsc greeter.ts複製代碼
編譯,這裏能夠發現以前埋下的雷已經暴露了,控制檯會打印錯誤信息,但這並不影響編譯,依然能夠編譯出.js文件。
setp:4
查看greeter.js,編譯已經沒有了指定的類型,這也是咱們熟悉的js
function greeter(person) {
return "Hello, " + person;
}
var user = 1;
document.body.textContent = greeter(user);複製代碼
使用vscode或者其餘typescript支持的編輯器,在編寫階段就能夠發現其錯誤
看了what,how,why後,再來看看ts基礎知識
ES6:
6種基礎類型:Undefined,Null,Boolean,Number,String, Symbol (es6)
1種複合類型:Object(對象包括數組,函數等)
TS:(表格來自某教學網站)
任意類型 | any |
聲明爲
any的變量能夠賦予任意類型的值。原es6聲明方式
|
數字類型 |
number |
雙精度64位浮點值。它能夠用來表示整數和分數。 let binaryLiteral: number = 0b1010; //
二進制
let octalLiteral: number = 0o744; //
八進制
let decLiteral: number = 6; //
十進制
let hexLiteral: number = 0xf00d; //
十六進制
|
字符串類型 |
string |
一個字符系列,使用單引號(')或雙引號(")來表示
字符串類型。反引號(`)來定義多行文本和內嵌表達式。
let name: string = "Runoob";let years: number = 5; let words: string = `您好,今年是${ name }發佈${ years + 1}週年`; |
布爾類型 |
boolean |
表示邏輯值:
true和false
。
let flag: boolean = true; |
數組類型 |
無 |
聲明變量爲數組。 //
在元素類型後面加上[]
let arr: number[] = [1, 2];
//
或者使用數組泛型
let arr: Array<number> = [1, 2];
|
元組 |
無 |
元組類型用來表示已知元素數量和類型的數組,各元素的類型沒必要相同,對應位置的類型須要相同。 let x: [string, number];x = ['Runoob', 1]; //
運行正常
x = [1, 'Runoob']; //
報錯
console.log(x[0]); //
輸出
Runoob
|
枚舉 |
enum |
枚舉類型用於定義數值集合。 enum Color {Red, Green, Blue}; let c: Color = Color.Blue;console.log(c); //
輸出
2
|
void |
void |
用於標識方法返回值的類型,表示該方法沒有返回值。 function hello(): void { alert("Hello Runoob");} |
null |
null |
表示對象值缺失。 |
undefined |
undefined |
用於初始化變量爲一個未定義的值 |
never |
never |
never
是其它類型(包括null和undefined)的子
類型,表明從不會出現的值。
|
能夠看到對比es6,ts增長了any、enum、void、元組、never。
any:這個類型更像是一個從js到ts過渡用的參數,萬物(對象)皆可any。這就像沒有引入ts的js,沒有指明類型,其實就是
let a //等同於 let a : any複製代碼
enum:枚舉類型,java中的枚舉類
void:表示這個方法沒有返回值,初學java時,是否是對public void main印象很深呢
元組:混合類型的數組,代表該數組中每一個元素的類型不相同,用元組去表示,
JS中你能夠不care每一個元素的類型
let arr = [1,'as',true,{'a':1}];複製代碼
可是TS明確類型這個概念,就要按照規矩辦事
let arr: number[] = [1, 2]; //ok
let arr: number[] = [1, '2']; //not ok ^_^複製代碼
元組的出現就是爲了讓數組可以擁有多類型,固然使用前要先肯定每一個位置對因而什麼類型的,規範了,可是也有點麻煩
let x: [string, number] = ['Runoob', 1];複製代碼
never:表示的是那些永不存在的值的類型,例如一個無限循環的方法,由於不存在因此是never,關於never就這樣簡單介紹下吧,平常使用中仍是比較少見的
function infiniteLoop(): never {
while (true) {}
}複製代碼
看完基礎的,再看點稍微進階的,以前說了TS是更趨向於面向對象編程的,那具體是怎麼表現的呢,es6的時候就已經引入了類和接口的概念,TS中又添加了一些功能,變得更像java了。
泛型(Generics)是指在定義函數、接口或類的時候,不預先指定具體的類型,而在使用的時候再指定類型的一種特性。
關於爲何引入泛型
TypeScript中不建議使用any類型,不能保證類型安全,調試時缺少完整的信息。
TypeScript可使用泛型來建立可重用的組件。支持當前數據類型,同時也能支持將來的數據類型。擴展靈活。能夠在編譯時發現你的類型錯誤,從而保證了類型安全。
就個人理解來講,當ts約束了方法的返回類型後,對於一些可複用的邏輯,但類型又不一致時,可使用泛型,擴展了方法的使用範圍。 舉個栗子
能夠看到當咱們想使用identity去做用number形式,ts的類型校驗會提示咱們不能夠,這時候確定會有人想到any,可是這是不推薦,在我理解any是個過渡用的,在嚴格的類型下極可能後面被踢出局,這時候就可使用泛型了,這裏泛型和java中是同樣同樣的
這樣就o了
看下編譯後的js
是否是有種what the f**k 的感受,脫褲子放屁嗎這不是,嘿嘿,把事情作規範確定會在原有的基礎上把一些東西複雜化,這點也是不少人吐槽的地方吧。
引入了public、private 和 protected修飾符明確類型中的方法及屬性的使用範圍,更清晰的定義了萬物皆對象的對象世界
public
修飾的屬性或方法是公有的,能夠在任何地方被訪問到,默認全部的屬性和方法都是 public
的
private
修飾的屬性或方法是私有的,不能在聲明它的類的外部訪問
protected
修飾的屬性或方法是受保護的,它和 private
相似,區別是它在子類中也是容許被訪問的
是否是和java的極其像,具體看一個例子 .ts 文件
私有屬性 private age只能在當前類中調用,在子類或者外部沒法調用,vscode中會直接提示Property 'age' is private and only accessible within class 'Animal'。
受保護的方法 protected sayWhoAmi()能夠在當前類,或者子類中調用,可是實例化對象中不能調用,一樣的vscode中會直接提示
有沒有注意到定義類的時候我用了abstract 這個修飾符,這也是TS新加入的屬性,抽象類,一種不容許實例化的類,對應的抽象方法,也是不容許實例化的,只可以由其子類去繼承。常見的比喻就是動物,動物是沒有具體的某個動物的(這裏的某個動物指這種東西就叫動物,好比說狗是狗,但它不叫作動物,它是動物的子類)。因此動物是個抽象的概念,咱們把活的生物統稱爲動物。這就是一個抽象類。抽象方法亦是,只有方法名,沒有方法體,由於它是將子類的方法歸納而來。例子中的sayHi( )抽象類中只定義了動物們都有打招呼的行爲,但並沒用說它們是怎麼打招呼的,由於不一樣的動物打招呼的方式多是不一樣的,狗說‘汪’,貓說‘喵’,人會說‘你好’,這就是在子類中去實現抽象方法。關於抽象好像扯得有點多,學過java的應該會比較容易理解。
看下上述代碼編譯後的樣子 .js文件
同時在文件的頂部生成了__extends方法
能夠看出爲了實現類的複雜關係,使用了方法的原型,對象的原型。關於__proto__,prototype這裏就不細說了,固然編譯後的js仍是會丟失一些類的屬性,編譯後的也只是運行而已,問題早在編寫的時候就發現了,這可能也是TS帶來的方便,經過類的繼承的機制取代原型和原型鏈在js中的應用。
一篇小總結總算寫完了,嘗試養成寫總結習慣的第一篇,但願不會太監(停更),簡單的梳理了下我眼中的TS,寫的也比較淺顯。在我看來對於TS,暫時保持一箇中立的態度吧,前期入手確定會加劇了工做量,可是減小了後期的維護成本。雖然類型判斷比較繁瑣,可是類型的使用仍是真香!
關於題目,想騷操做一把,可是自己就是個錯誤
console.log(typeof typescript === 'javascript' ) 複製代碼
這個不用想確定是false了
typeof xxx 的範圍只會在[ 'undefined' ,'boolean' ,'string' ,'number','object' , 'function' ,'symbol' ]
typeof null === "object" //true 這點注意下複製代碼
固然了 事實證實TS和JS 也不是一個東西啊,哦,他們原本也不是個東西,它們是前端的語言。
想進一步瞭解TS能夠參考一下連接,學任何東西官方文檔永遠是最nice的,其餘的都是幫助理解用的
官方文檔:www.typescriptlang.org/index.html
中文文檔:ts.xcatliu.com/
菜鳥教程:www.runoob.com/typescript/…
本文中斜體內容,均摘抄上述網站。