近日Node.js之父瑞安達爾(Ryan Dahl)釋出新的開源專案 deno,從官方介紹來看,可以認為它是下一代 Node,使用 rust 語言代替 C++ 重新編寫跨平臺底層核心驅動,上層仍然使用 V8 引擎,最終提供一個安全的 TypeScript 執行時。
甚至Dahl在公開場合表示Node.js已經無力迴天,Deno將是他的代替品。我相信前端小夥伴們一定都聽說了這個訊息。
本文首發jspang.com ,轉載請標明出處,開源不易,且行且珍惜。
視訊目錄
第01節:初識TypeScript
Deno都要來了,還不學TypeScript?
近日Node.js之父瑞安達爾(Ryan Dahl)釋出新的開源專案 deno,從官方介紹來看,可以認為它是下一代 Node,使用 Go 語言代替 C++ 重新編寫跨平臺底層核心驅動,上層仍然使用 V8 引擎,最終提供一個安全的 TypeScript 執行時。
甚至Dahl在公開場合標識Node.js已經無力迴天,Deno將是他的代替品。我相信前端小夥伴們一定都聽說了這個訊息。
Deno開始使用後用TypeScript變成了一個必會的技能,但是很多小夥伴們還不太熟悉TypeScript的用法。其實TypeScript現在用的已經很廣泛了,無論你使用ng、React還是Vue都可以使用TypeScript來實現的你JavaScript程式碼。
小夥伴們快準備好你們的電腦,跟著技術胖一起學習吧。再不學習就被這個時代拋棄了,正如那句流行的話:
時代拋棄你時,連一聲再見都不會說。
TypeScript是什麼?
TypeScript 是一種由微軟開發的自由和開源的程式語言。它是 JavaScript 的一個超集,TypeScript 在 JavaScript 的基礎上新增了可選的靜態型別和基於類的物件導向程式設計。
其實TypeScript就是相當於JavaScript的增強版,但是最後執行時還要編譯成JavaScript。TypeScript最大的目的是讓程式設計師更具創造性,提高生產力,它將極大增強JavaScript編寫應用的開發和除錯環節,讓JavaScript能夠方便用於編寫大型應用和進行多人協作。
TypeScript和JavaScript的對比
TypeScript 與JavaScript兩者的特性對比,主要表現為以下幾點:
- TypeScript是一個應用程式級的JavaScript開發語言。(這也表示TypeScript比較牛逼,可以開發大型應用,或者說更適合開發大型應用)
- TypeScript是JavaScript的超集,可以編譯成純JavaScript。這個和我們CSS離的Less或者Sass是很像的,我們用更好的程式碼編寫方式來進行編寫,最後還是有好生成原生的JavaScript語言。
- TypeScript跨瀏覽器、跨作業系統、跨主機、且開源。由於最後他編譯成了JavaScript所以只要能執行JS的地方,都可以執行我們寫的程式,設定在node.js裡。
- TypeScript始於JavaScript,終於JavaScript。遵循JavaScript的語法和語義,所以對於我們前端從業者來說,學習前來得心應手,並沒有太大的難度。
- TypeScript可以重用JavaScript程式碼,呼叫流行的JavaScript庫。
- TypeScript提供了類、模組和介面,更易於構建元件和維護。
第02節:開發環境的安裝
已經對TypeScript有了大概的瞭解,我的部落格全是注重實際,所以不講那麼多理論了,直接開始上手。這節我們開始搭建TypeScript的開發環境。
1.安裝Node.js
安裝Node.js非常簡單,只要到Node官網下載一個最新版本就可以了:nodejs.org/zh-cn/.在win… 安裝好後,可以開啟命令列工具,同時按下win+R,然後輸入cmd就可以開啟,開啟後輸入
node -v
npm -v
複製程式碼
如果看到版本號說明已經安裝成功了,看不到版本號就說明你的node.js沒有安裝成功。
2.安裝TypeScript包
在剛才的命令列視窗繼續輸入如下命令:
npm install typescript -g
tsc --version
複製程式碼
需要注意的是:如果你是mac電腦,要使用sudo npm install typescript -g
指令進行安裝
3.編寫HelloWorld程式
-
初始化專案:進入你的程式設計資料夾後,可以使用
npm init -y
來初始化專案,生成package.json檔案。 -
建立
tsconfig.json
檔案,在終端中輸入tsc --init
:它是一個TypeScript
專案的配置檔案,可以通過讀取它來設定TypeScript
編譯器的編譯引數。 -
安裝@types/node,使用
npm install @types/node --dev-save
進行安裝。這個主要是解決模組的宣告檔案問題。 -
編寫
HelloWorld.ts
檔案,然後進行儲存,程式碼如下。
var a:string = "HelloWorld"
console.log(a)
複製程式碼
-
在Vscode的任務選單下,開啟執行生成任務,然後選擇tsc:構建-tsconfig.json,這時候就會生成一個
helloWorld.js
檔案 -
在終端中輸入
node helloWorld.js
就可以看到結果了。
**總結:**這節課雖然簡單,但是小夥伴們一定要動手操作,如果不操作,或者開發環境配置不好,下面的課程就不好學習了。
第03節:變數型別的那些事
這個文章很久沒有更新了,很多小夥伴剛開始看就放下了(我對不起你們),也有很多人認為技術胖放棄了這篇文章。我是不會放棄的,讓我們快複習一下前兩節的課程後,繼續學習吧。TypeScript
最大的一個特點就是變數是強型別的,也就是說,在宣告變數的時候,我們必須給他一個型別。比如:字串、數字、布林,列舉........ 就用這節課全面瞭解一下typeScript的宣告型別。
TypeScript中的資料型別有:
- Undefined :
- Number:數值型別;
- string : 字串型別;
- Boolean: 布林型別;
- enum:列舉型別;
- any : 任意型別,一個牛X的型別;
- void:空型別;
- Array : 陣列型別;
- Tuple : 元祖型別;
- Null :空型別。
Undefined型別
在js中當你定義了一個變數,但沒有給他賦予任何值的時候,他就是Undefined型別。這可能和你以前學的語言稍有不同,其他語言會有個型別的預設值。
我們現在來看一個例子,比如我們要宣告一個年齡的變數age
,我們要使用數值型別,也就是Number
,但是我們不給他任何的值,我們只是在控制檯給它輸出,然後我們來看結果。
新建demo01.ts檔案,下入下面程式碼:
//宣告數值型別的變數age,但不予賦值
var age:number
console.log(age)
複製程式碼
寫完後儲存程式碼,進行執行任務,然後生成demo01.js,在終端中使用node demo01.js
來進行檢視執行結果。控制檯輸出了undefined
,跟我們預想的一模一樣。
Number型別
在TypeScript中,所有的數字都是Number型別,這不分是整數還是小數。比如下面我們宣告一個年齡是18歲,身高是178.5釐米。
新建一個檔案demo01_1.ts檔案,寫入下面程式碼:
var age:number = 18
var stature:number = 178.5
console.log(age)
console.log(stature)
複製程式碼
然後執行轉換,檢視結果,我們可以在控制檯看到結果已經順利輸出,沒有任何意外。
在TypeScrip中有幾種特殊的Number型別 我們需要額外注意一下:
- NaN:它是Not a Number 的簡寫,意思就是不是一個數值。如果一個計算結果或者函式的返回值本應該是數值,但是由於種種原因,他不是數字。出現這種狀況不會報錯,而是把它的結果看成了NaN。(這就好比我們去泰國外,找了一個大長腿、瓜子臉、水蛇腰的女神。房也開好了,澡也洗完了,發現跟我們的性別統一,我們只能吃個啞巴虧,你絕不會聲張)
- Infinity :正無窮大。
- -Infinity:負無窮大。
string型別
由單引號或者雙引號括起來的一串字元就是字串。比如:“技術胖”,'jspang.com'。看下面的程式碼:
demo01_2.ts
var jspang:string = "技術胖 jspang.com"
console.log(jspang)
複製程式碼
這時候控制圖就會乖乖的輸出技術胖 jspang.com
.
boolean布林型別
作任何業務邏輯判斷都要有布林型別的參與,通過對與錯的判斷是最直觀的邏輯處理。boolean型別只有兩種值,true和false。
var b:boolean = true
var c:boolean = false
複製程式碼
enum 型別
這個世界有很多值是多個並且是固定的,比如:
- 世界上人的型別:男人、女人、中性
- 一年的季節:春、夏、秋、冬 ,有四個結果。
這種變數的結果是固定的幾個資料時,就是我們使用列舉型別的最好時機:
demo01_3.ts
enum REN{ nan , nv ,yao}
console.log(REN.yao) //返回了2,這是索引index,跟陣列很想。
複製程式碼
如果我們想給這些列舉賦值,可以直接使用=
,來進行賦值。
enum REN{
nan = '男',
nv = '女',
yao= '妖'
}
console.log(REN.yao) //返回了妖 這個字
複製程式碼
any型別
一個寫慣了前端的人,有時候不自覺的就分不清型別了。這是個不好的習慣,也是前端的痛,就因為這個原因,JavaScript也多次被人詬病說大型專案不適合用JavaScript。但是習慣一旦養成,改是需要時間和磨練的。TypeScript友好的為我們提供了一種特殊的型別any
,比如我們在程式中不斷變化著型別,又不想讓程式報錯,這時候就可以使用any了。
var t:any =10
t = "jspang"
t = true
console.log(t)
複製程式碼
Null型別:
與 Undefined 類似,都代表空。Null 代表是引用型別為空。意義不大,但是有用。後續學習中會使用到。
注意:剩餘的陣列、元組、void 會在後續的章節中講解。
第04節:TypeScript的函式
比如現在我們有個找小姐姐的需求:
- 找18歲的小姐姐
- 找28歲的小姐姐
- 找38歲的小姐姐
這個時候你會怎麼作?難道要把程式碼寫3遍嗎?也許新手會這樣作的,但是作為一個有多年開車經驗的老司機,技術胖肯定會建立一個找小姐姐的機器,這就是函式。
正經點說是:
我們可以把功能相近的需求封裝成一個獨立的程式碼塊,每次傳入不同的變數或引數,就可以實現不同的結果。
定義函式
函式就相當於一個工具,如果你想使用這個工具,就要先製作這個工具。這就是我們說的定義函式。在TypeScript裡定義函式跟JavaScript稍微有些不同。我們來定義找小姐姐的函式吧。
function searchXiaoJieJie(age:number):string{
return '找到了'+age+'歲的小姐姐'
}
var age:number = 18
var result:string = searchXiaoJieJie(age)
console.log(result)
複製程式碼
上面的程式,先用function關鍵字宣告瞭一個searchXiaoJieJie
的方法,然後我們使用了他,並返回了給我們結果。
需要注意的是:
- 宣告(定義)函式必須加 function 關鍵字;
- 函式名與變數名一樣,命名規則按照識別符號規則;
- 函式引數可有可無,多個引數之間用逗號隔開;
- 每個引數引數由名字與型別組成,之間用分號隔開;
- 函式的返回值可有可無,沒有時,返回型別為 void;
- 大括號中是函式體。
形參和實參
形參的使用
函式定義的時候寫的引數是形參。從字面意義上我們可以看出,形參就是形式上的引數。我們定義了形參也就規定了此函式的引數個數和引數型別,規範了函式。
function searchXiaoJieJie(age:number):string{
return '找到了'+age+'歲的小姐姐'
}
複製程式碼
比如這個函式,就定義了一個形參,它的型別是數值型別。
實參的使用
呼叫函式時傳遞的具體值就是實參。同樣從字面理解,實參就是真實的引數,我們在使用的時候,具體真實傳遞過去的就是實參,比如18,20,22,這些具體的引數就是實參。
打個比方,我們去按摩,需要找技師,當我們還沒有找的時候,這時候就是形參。當一個個技師站好了,讓你選。你最終選擇了一個,這就是實參。實參在真實使用時才傳遞。
var result:string = searchXiaoJieJie(age)
複製程式碼
注意
在函式呼叫的時候,我們需要按照形參的規則傳遞實參,有幾個形參就要傳遞幾個實參,並且每一個實參的型別要與對應的形參型別一致。
TypeScript語言中的函式引數
TypeScript的函式引數是比較靈活的,它不像那些早起出現的傳統語言那麼死板。在TypeScript語言中,函式的形參分為:可選形參、預設形參、剩餘引數形參等。
1.有可選引數的函式
可選引數,就是我們定義形參的時候,可以定義一個可傳可不傳的引數。這種引數,在定義函式的時候通過?
標註。
比如我們繼續作找小姐姐的函式,這回不僅可以傳遞年齡,還可以選擇性的傳遞身材。我們來看如何編寫。
function searchXiaoJieJie2(age:number,stature?:string):string{
let yy:string = ''
yy = '找到了'+age+'歲'
if(stature !=undefined){
yy = yy + stature
}
return yy+'的小姐姐'
}
var result:string = searchXiaoJieJie2(22,'大長腿')
console.log(result)
複製程式碼
2.有預設引數的函式
有預設引數就更好理解了,就是我們不傳遞的時候,他會給我們一個預設值,而不是undefined
了。我們改造上邊的函式,也是兩個引數,但是我們把年齡和身材都設定預設值,這就相當於熟客,我們直接來一句照舊是一樣的。
function searchXiaoJieJie2(age:number=18,stature:string='大胸'):string{
let yy:string = ''
yy = '找到了'+age+'歲'
if(stature !=undefined){
yy = yy + stature
}
return yy+'的小姐姐'
}
var result:string = searchXiaoJieJie2()
console.log(result)
複製程式碼
3.有剩餘引數的函式
有時候我們有這樣的需求,我傳遞給函式的引數個數不確定。例如:我找小姐姐的時候有很多要求,個人眼光比較挑剔。這時候你不能限制我,我要隨心所欲。
說的技術點,剩餘引數就是形參是一個陣列,傳遞幾個實參過來都可以直接存在形參的陣列中。
function searchXiaoJieJie3(...xuqiu:string[]):string{
let yy:string = '找到了'
for (let i =0;i<xuqiu.length;i++){
yy = yy + xuqiu[i]
if(i<xuqiu.length){
yy=yy+'、'
}
}
yy=yy+'的小姐姐'
return yy
}
var result:string = searchXiaoJieJie3('22歲','大長腿','瓜子臉','水蛇腰')
console.log(result)
複製程式碼
有了這個引數形式,我們好像無所不能了,我愛程式設計,程式設計讓我幸福。好吧,這節課我們就先到這裡,下節課我們繼續找小姐姐去。不是,不是,是繼續學習。
第05節:三種函式的定義方式
上節課用引數的形式來區分了TypeScript裡函式的定義方法,但這並不能完全包含所有的定義方法,所以再以宣告的形式,而不是引數來總結幾個方法。
函式宣告法
函式宣告法建立函式是最常用的函式定義法。使用function關鍵字和函式名去定義一個函式。
function add(n1:number,n2:number):number{
return n1+n2
}
複製程式碼
函式表示式法
函式表示式法是將一個函式賦值給一個變數,這個變數名就是函式名。通過變數名就可以呼叫函式了。這種方式定義的函式,必須在定義之後,呼叫函式。下面例子中等號右邊的函式沒有函式名,稱為匿名函式。
var add = function(n1:number,n2:number):number{
return n1+n2
}
console.log(add(1,4))
複製程式碼
箭頭函式
箭頭函式是 ES6 中新增的函式定義的新方式,我們的 TypeScript 語言是完全支援 ES6 語法的。箭頭函式定義的函式一般都用於回撥函式中。
var add = (n1:number,n2:number):number=>{
return n1+n2
}
console.log(add(1,4))
複製程式碼
第06節:函式中變數的作用域
通過兩節對TypeScript的學習,再加上如果你以前JavaScript的知識很紮實,你一定知道函式類似於一個封閉的盒子。盒子裡面的世界和外面的世界是不一樣的。有點像人的外在表現和內在性格,雖然相輔相成,相生相剋,但是完全不一樣。定義在函式內部的變數與定義在函式外部的變數也是不一樣的,他們起作用的範圍也不一樣。
每個變數都有一個起作用的範圍,這個範圍就是變數的作用域。在TypeScript語言中變數作用域劃分是以函式為標準的。
函式作用域演示
我們來舉個例子,現在要製作一個整形的方法,然後在函式裡用var
定義一個yangzi
的變數,我們再函式的外部讀取這個變數,你會發現是讀取不到的。
function zhengXing():void{
var yangzi = '劉德華'
console.log(yangzi)
}
zhengXing()
console.log(yangzi)
複製程式碼
認識全域性變數和區域性變數
現在我們對函式的作用域有了一點了解,那麼到底什麼是全域性變數,什麼又是區域性變數那?這個問題很多面試中都會提問,所以跟你的前途息息相關。
- 區域性變數:函式體內定義的變數就是區域性變數。
- 全域性變數: 函式體外 定義的變數就是全域性變數。
我們改造上邊的程式,把yangzi
辦理移動到全域性,然後再進行輸出。
var yangzi = '劉德華'
function zhengXing():void{
console.log('技術胖整形成了'+yangzi+'的樣子')
}
zhengXing()
console.log(yangzi)
複製程式碼
這時候yangzi
變數是全域性的,所以在函式內也可以呼叫,在函式外也可以呼叫。
區域性變數和全域性變數重名
當區域性變數與全域性變數重名的時候,在函式體內是區域性變數起作用;如果重名,就有變數提升,這是一個坑,小夥伴們必須要注意
還是上邊整形的例子,技術胖是想整形成劉德華,但是函式體內部宣告瞭一個馬德華。雖然一字之差,但是樣子可是完全不同的。我們來看程式碼如何實現:
var yangzi:string = '劉德華'
function zhengXing():void{
var yangzi:string = '馬德華'
console.log('技術胖整形成了'+yangzi+'的樣子')
}
zhengXing()
console.log(yangzi)
複製程式碼
這回你會發現,技術胖並沒有變成劉德華而是變成了馬德華。那你說我我想變成劉德華,我在函式沒宣告新變數前列印到控制檯行不行?
var yangzi:string = '劉德華'
function zhengXing():void{
console.log('技術胖整形成了'+yangzi+'的樣子')
var yangzi:string = '馬德華'
console.log('技術胖整形成了'+yangzi+'的樣子')
}
zhengXing()
console.log(yangzi)
複製程式碼
程式碼改造成了這樣,但是你會發現,我們輸出的結果如下:
技術胖整形成了undefined的樣子
複製程式碼
產生這個結果的原因就是變數提升,他的真實程式碼是這樣的。
var yangzi:string = '劉德華'
function zhengXing():void{
var yangzi:string
console.log('技術胖整形成了'+yangzi+'的樣子')
yangzi = '馬德華'
console.log('技術胖整形成了'+yangzi+'的樣子')
}
zhengXing()
console.log(yangzi)
複製程式碼
也就是當內部宣告瞭和全域性的變數同名時,就會出現變數提升的效果,宣告語句會提升到函式的第一句。這就是著名的變數提升效果。
let關鍵字變數的作用域
在早期javascript的變數作用域只有全域性和區域性,並且是以函式劃分的,但在其他語言中,作用域的劃分是以一對大括號作為界限的。
所以,JavaScript就遭到了無數開發者的吐槽,甚至說javascript不適合開發大型語言,容易記憶體溢位。JavaScript團隊意識到了這一點,在ES6中推出了let關鍵字。
使用let關鍵字的變數就是一個塊級作用域變數。希望大家在實際工作中多使用let來宣告你的變數,讓你的程式更有條例。 來看一端程式:
function zhengXing():void{
var yangzia:string = '劉德華'
{
let yangzib:string = '小瀋陽'
console.log('技術胖整形成了'+yangzib+'的樣子')
}
console.log('技術胖整形成了'+yangzia+'的樣子')
console.log('技術胖整形成了'+yangzib+'的樣子')
}
zhengXing()
複製程式碼
這時候編譯後,我們執行,你會發現是可以執行的,並且列印到了控制檯正確的結果。
這是因為ts編譯成js,他自動給我們加了ES5的處理,ES5裡是沒有let關鍵字的,現在我們再改一下編譯好的程式,你會發現yangzib
這個關鍵字就找不到了(詳情看視訊吧)。
第07節:引用型別-陣列
TypeScript中的資料分為值型別和引用型別。值型別我們前幾節課講的都是,但是引用型別我們在這套視訊中還沒有講解。我們先來看一個引用型別的例子,來個初步印象。
初識引用型別
現在把“技術胖”虛擬成一個物件,然後來使用過它,具體看下面的程式碼:
let jspang = {
name:'技術胖',
website:'jspang.com',
age:18,
saySometing:function(){
console.log('為了前端技術')
}
}
console.log(jspang.name)
jspang.saySometing()
複製程式碼
通過上面的案例,我們看到引用型別是一種複合的資料型別,引用型別中封裝了很多對屬性,每一對屬性都有屬性名和屬性值。屬性名是字串,屬性值是任意型別的資料。可以通過變數名和屬性名獲取屬性的值或者呼叫屬性的方法。
在TypeScript中也給我們提供了一些引用型別,例如:Array(陣列)、String(字串)、Date(日期物件)、RegExp(正規表示式)等。我們將用幾節課的時間來學習這些用用型別,以及其中封裝的常用方法和屬性。
初始化陣列的兩種方法
你學習這個課程一定對js中的陣列有所瞭解,要使用一個陣列,首先要學會建立一個陣列。建立陣列時可以指定陣列的容量,也可以直接向陣列中儲存資料。
宣告陣列的方法
宣告陣列跟宣告一個普通變數是一樣的,都是通過 var let 關鍵字實現的,只不過陣列的型別說明符比較複雜而已。
let arr1:number[ ] //宣告一個數值型別的陣列
let arr2:Array<string> //宣告一個字串型別的陣列
複製程式碼
給陣列賦值
陣列是儲存大量資料的集合,宣告陣列之後,需要給陣列儲存資料。這時候有兩種方法:
- 字面量賦值法:直接使用“[ ]”對陣列進行賦值。
- 建構函式賦值法:
** 字面量賦值法**
//定義一個空陣列,陣列容量為0
let arr1:number[] = []
//定義一個陣列時,直接給陣列賦值
let arr2:number[] = [1,2,3,4,5]
//定義陣列 的同事給陣列賦值
let arr3:Array<string> = ['jspang','技術胖','金三胖']
let arr4:Array<boolean> = [ true,false,false]
複製程式碼
需要注意的是,在TypeScript中指定資料型別的陣列只能儲存同一型別的陣列元素。
//報錯! 必須儲存number型別的資料
let arr5:number[] = [1,2,true]
複製程式碼
建構函式賦值法
在 TypeScript 中使用 Array 這個引用型別來表示陣列的,那麼每一個陣列都是 Array 型別的例項。那麼,我們在建立陣列的時候也可以使用建構函式來進行賦值。
let arr1:number[] = new Array()
let ara2:number[] = new Array(1,2,3,4,5)
let arr3:Array<string> = new Array('jspang','技術胖','金三胖')
let arr4:Array<boolean> = new Array(true,false,false)
複製程式碼
這兩種方法,都可以給陣列進行賦值,在實際開發中使用哪種方法都是可以的。
認識元祖,一種特殊的陣列
元祖是一種特殊的陣列,元祖型別允許表示一個已知元素數量和型別的陣列,各元素的型別不必相同。比如,你可以定義一對值分別為string和number型別的元祖。元祖在實際開發中使用的非常少,大家瞭解一下就可以了,不做過多介紹。
//宣告一個元祖型別
let x : [string,number]
//正確的初始化
x = ['hello',10]
//錯誤的初始化方法
x = [10,'hello']
複製程式碼
TypeScript中其它的陣列知識跟JavaScript中的一樣,我再這裡就不磨磨唧唧的浪費大家時間了。感興趣的可以寫一下JS中的陣列方法。
在實際專案中陣列的使用還是非常非常多的,這也算是一種前端開發者的硬功夫,所以要多練習。
第08節:引用型別-字串啊
通過上節學習你一定對引用型別有了一個很好的認識。在TypeScript中存在兩種型別的字串:基本型別字串和引用型別字串。
字串的兩種型別
- 基本型別字串:由單引號或者雙引號括起來的一串字串。
- 引用型別字串:用new 例項化的 String型別。
那為什麼會出現這種情況那,有的小夥伴會認為是不是當時JavaScript的開發人員腦子進水了。其實不是的,在前端開發,操作字串是最普遍的一種操作。JavaScript的開發人員為了大家更容易的操作字串,有了引用型別的字串就可以給字串增加一系列方法了。
let jspang:string = '技術胖'
let jspanga:String = new String("jspang.com")
console.log(jspang)
console.log(jspanga)
複製程式碼
編譯以後我們使用node
執行這段程式碼,你可以看到控制檯輸出了的結果,這可能跟你心裡想的不太一樣。
技術胖
[String: 'jspang.com']
複製程式碼
需要說明的是這兩種宣告字串的方法沒有什麼不同。基本型別的字串可以直接使用引用型別的屬性和方法。
字串的長度length
使用length就可以來獲取字串的長度,當然作為一個男人知道自己的長度是非常有必要的.....不好意思,我又開始汙了。那我們來看看下面獲取長度的列子。
let jspang:string = '技術胖'
let jspanga:String = new String("jspang.com")
console.log(jspang.length)
console.log(jspanga.length)
複製程式碼
字串常用的方法
為了一些剛剛接觸前端的小夥伴,我還是講解一下字串的常用方法,如果你已經有了很好的JS的基礎,下面的內容可以完全跳過的。
查詢字串
從頭部查詢字串直接使用indexOf就可以了。
基本語法:str.indexOf(subStr)
我們來一個找小姐姐的例子:現在我們寫一段話,這段話當然是一個字串,比如:“清早起來開啟窗,心情美美的,我要出去找小姐姐,心情美美的。”然後找出“小姐姐”的位置。
let something:string = "清早起來開啟窗,心情美美的,我要出去找小姐姐,心情美美的。"
let xiaoJieJie:string = "小姐姐"
console.log(something.indexOf(xiaoJieJie)) //19
複製程式碼
如果我們查詢的字串沒有找到,則返回-1。
從字串尾部開始查詢字串的位置,使用lastIndexOf( )
let something:string = "清早起來開啟窗,心情美美的,我要出去找小姐姐,心情美美的。"
let xiaoJieJie:string = "小姐姐"
console.log(something.lastIndexOf(xiaoJieJie)) //19
複製程式碼
需要注意的是,返回的都是字串的下標。所以返回的值是相同的。並不是返回從後到前的下標位置。這個新手很容易採坑。
擷取字串
基本語法如下:
str.substring(startIndex,[endIndex])
複製程式碼
引數 startIndex 表示開始下標,endIndex 表示結束下標,endIndex 引數是可選的。該方法的作用是從指定的開始下標開始擷取字串,擷取到 endIndex 的下標之前,如果沒有 endIndex,則擷取到字串結束。
我們還是上面的例子,現在我們擷取不同的字串。
let something:string = "清早起來開啟窗,心情美美的,我要出去找小姐姐,心情美美的。"
let xiaoJieJie:string = "小姐姐"
console.log(something.substring(8))
console.log(something.substring(8,14))
複製程式碼
替換字串
基本語法如下:
str.replace(subStr,newstr);
複製程式碼
substr 表示被替換的子串,newstr 表示要替換成的子串。該方法的作用是在 str 中從頭部開始找 substr 子串,找到之後,把 substr 用 newstr 替換掉。需要注意的是如果 str 中有多個 substr 子串,只有第一個 substr 子串會被替換掉。
現在我們要把上面字串裡的小姐姐替換成小哥哥,我們看看具體程式碼的實現。
let something:string = "清早起來開啟窗,心情美美的,我要出去找小姐姐,心情美美的。"
let xiaoJieJie:string = "小姐姐"
console.log(something.replace(xiaoJieJie,'小哥哥'))
複製程式碼
就給大家講這麼多方法吧,如果你想了解更多操作,可以看javascript相關的書籍來進行學習。下節課我們來看看引用型別的-日期相關的操作。
第09節:引用型別-日期物件
TypeScript中使用Date這個引用型別來儲存日期物件,如果你要宣告一個日期變數時,記得也要註明它的型別是Date。
建立日期物件
日期物件是Date的例項,可以使用建構函式的方法進行建立。並且建構函式中可以傳遞多種型別的引數。
1.不傳遞任何引數
建構函式中不傳遞引數時,Date()建構函式將根據當前日期和時間建立一個Date物件。我們看下面的例子理解一下。
let d:Date = new Date()
console.log(d)
複製程式碼
這時候執行node
的結果如下:
2018-09-06T06:48:12.504Z
複製程式碼
2.傳遞一個整數
傳遞一個整數,這個整數代表的是距離1970-01-01 00:00:00
的毫秒數(具體為什麼是這個時間,小夥伴可以自己百度一下)。例如:傳入引數為1000,將建立一個表示1970-01-01 00:00:01
的日期物件。
我們舉個例子,傳遞一個整數,看一下結果。
let d:Date = new Date(1000)
let da:Date = new Date(2000)
console.log(d) //1970-01-01T00:00:01.000Z
console.log(da) //1970-01-01T00:00:02.000Z
複製程式碼
3.傳遞一個字串
如果傳遞一個表示日期的字串,就會生成相對應的日期物件。字串的格式常用:yyyy/MM/dd hh:mm:ss
,yyyy-MM-dd hh:mm:ss
,yyyy-MM-ddThh:mm:ss
等,具體可以參看下面的例子。
let d1:Date = new Date('2018/09/06 05:30:00')
let d2:Date = new Date('2018-09-06 05:30:00')
let d3:Date = new Date('2018-09-06T05:30:00')
console.log(d1)
console.log(d2)
console.log(d3)
複製程式碼
當然,他們列印出來的結果時完全相同的,所以在開發中你不用太過於糾結使用哪種方式進行宣告。
4.傳遞表示年月日時分秒的變數
let d:Date = new Date(year,month,day,hours,minutes,seconds,ms);
複製程式碼
- year 表示年份,4位數字。
- month表示月份,數值是0(1月)~11(12月)之間的整數。
- day 表示日期。數值是1~31之間的整數。
- hours 表示小時,數值是0-23之間的整數。
- minutes 表示分鐘數,數值是0~59之間的整數。
- seconds 表示秒數,數值是0~59之間的整數。
- ms 表示毫秒數,數值是0~999之間的整數。
至於Date型別的方法,跟JavaScript完全一樣,所以我就不在重複講述了,要不就變成講JavaScript了。
第10節:引用型別-正規表示式
前端對使用者輸入的資訊進行驗證,比如手機號,年齡,三圍(我又要開始汙了)。用於驗證最好最強大的手段目前為止就是正規表示式。TypeScript的RegExp類表示正規表示式。這節我們就學習一下TypeScript裡的正規表示式吧。
認識正規表示式
建立正規表示式和字串猶如一對好基友(類似),建立正規表示式也提供了兩種方法,一種是才採用new 關鍵字,另一種是採用字面量的方式。
建構函式法
建構函式中可以傳一個引數,也可以傳遞兩個引數。一個是字串描述,另一個是修飾符,比如g是全域性修飾符,i是忽略大小寫,m是多行模式。
舉個例子:
let reg1:RegExp = new RegExp("jspang") //表示字串規則裡含有jspang
console.log(reg1)
let reg2:RegExp = new RegExp("jspang",'gi')
console.log(reg2)
複製程式碼
其實現在列印出來的就是字面量的賦值方法。我們可以在視訊中看到輸出的結果。
字面量法
其實建構函式的方法我個人用的是比較少的,我都會使用字面量法來宣告正規表示式。
let reg3:RegExp = /jspang/
let reg4:RegExp = /jspang/gi
複製程式碼
RegExp中的常用方法
RegExp物件包含兩個方法:test( )和exec( ),功能基本相似,用於測試字串匹配。
- test(string) :在字串中查詢是否存在指定的正規表示式並返回布林值,如果存在則返回 true,不存在則返回 false。
- exec(string) : 用於在字串中查詢指定正規表示式,如果 exec() 方法執行成功,則返回包含該查詢字串的相關資訊陣列。如果執行失敗,則返回 null。
來看一個test的例子:
let reg1:RegExp = /jspang/i
let website:string = 'jspang.com'
let result:boolean = reg1.test(website)
console.log(result) //true
複製程式碼
這時候控制檯列印出來的是true,那麼我們再來看一下exec
的使用方法。
let reg1:RegExp = /jspang/i
let website:string = 'jspang.com'
console.log(reg1.exec(website))
//[ 'jspang', index: 0, input: 'jspang.com' ]
複製程式碼
輸出的結果變為了[ 'jspang', index: 0, input: 'jspang.com' ]
。
剩下的就是正規表示式的語法了,這個好像是學程式的都要進行學習。如果你還不屬性,可以檢視一下這篇文章:www.runoob.com/regexp/rege…
正則在工作中的用法很多,需要你慢慢積累經驗。
第11節: 物件導向程式設計-類的宣告和使用
TypeScript提供了強大的類的支援,作為一個程式設計師一定要學會類的使用,因為只有會了類
才可以new出物件來,否者可能會單身一輩子哦(開個玩笑) 。類的出現可以讓前端程式設計師抽象層次、增加維護性和複用性。當然這一系列的類的操作,我們都叫他物件導向程式設計。TypeScript就是一個基於類的物件導向程式語言。
認識類與物件
類是物件具體事務的一個抽象,物件是類的具體表現。
舉個例子,比如說,有人給你介紹物件,會問你的要求。那麼,你的要求是:身高165以上,體型偏瘦,長頭髮,大眼睛。從事正當穩定的工作,會做飯等等。這些要求就是對你心中理想伴侶的一個抽象,就是類。介紹人按照你的要求給你找的這些女生,就是類的例項,就是物件。
類的定義
認識TypeScript基於類的物件導向程式設計,就需要從一個簡單的類開始。
我們模擬一個小姐姐的類,小姐姐需要有年齡,有姓名,會說“小哥哥好”。
看下面的例子:
class XiaoJieJie{
name:string;
age:number;
constructor(name:string,age:number){
this.name = name
this.age = age
}
say(){
console.log('小哥哥好')
}
}
let jiejie:XiaoJieJie = new XiaoJieJie('范冰冰',18)
console.log(jiejie)
jiejie.say()
複製程式碼
我們先用class關鍵字宣告瞭一個類,並在裡邊宣告瞭name
和age
屬性。constructor
為建構函式。建構函式的主要作用是給類中封裝的屬性進行賦值。
使用和定義類其實很簡單,關鍵是理解類的思想。要有抽象邏輯的能力,這樣才能複用和增強維護性。
第12節: 物件導向程式設計-修飾符
類中的修飾符是最常見的,TypeScript為我們準備了豐富的修飾符,小夥伴們可以和我一起學習一下修飾符。
訪問修飾符
TypeScript語言和Java還有C#很像(因為我只會這兩個物件導向的語言),類中屬性的訪問可以用訪問修飾符來進行限制。訪問修飾符分為:public、protected、private。
- public:公有修飾符,可以在類內或者類外使用public修飾的屬性或者行為,預設修飾符。
- protected:受保護的修飾符,可以本類和子類中使用protected修飾的屬性和行為。
- private : 私有修飾符,只可以在類內使用private修飾的屬性和行為。
我們還是寫一個小姐姐的類,但是我們使用一些訪問修飾符來修飾。
詳細講解,請看視訊。
class XiaoJieJie2{
public sex:string
protected name:string
private age:number
public constructor(sex:string,name:string,age:number){
this.sex=sex
this.name=name
this.age=age
}
public sayHello(){
console.log('小哥哥好')
}
protected sayLove(){
console.log('我愛你')
}
}
var jiejie2:XiaoJieJie2 = new XiaoJieJie2('女','熱巴',22)
console.log(jiejie2.sex)
console.log(jiejie2.name) //報錯
console.log(jiejie2.age) //報錯
jiejie2.sayHello()
jiejie2.sayLove() //報錯
複製程式碼
你可以在寫程式碼的時候,就會發現,編輯器已經給我們報錯了。
只讀屬性修飾符
使用readonly修飾符將屬性設定為只讀,只讀屬性必須在生命時或者建構函式裡被初始化(注意)。
我們宣告一個man的抽象類,裡邊只有一個屬性sex
,並且是隻讀。
class Man{
public readonly sex:string = '男'
}
var man:Man = new Man()
man.sex='女'
複製程式碼
在編輯器裡你就會發現報錯了,我們就不強行編譯了。
第13節: 物件導向程式設計-繼承和重寫
我錄這節課的時候,炎熱的夏天正好退去,秋高氣爽,天藍雲白,又到了人類繁衍生息的季節(汙是必須的)。那我們就講講繁衍的事情......繼承和重寫。
類的繼承
在使用TypeScript這門語言時,一個最重要基本功就是物件導向程式設計,那對類的擴充套件就變的格外重要,擴充套件經常使用的手段就是繼承。
繼承:允許我們建立一個類(子類),從已有的類(父類)上繼承所有的屬性和方法,子類可以新建父類中沒有的屬性和方法。
我們先來建立一個父類,這個父類完全抽象了技術胖的特點。
class Jspang{
public name:string
public age : number
public skill: string
constructor(name:string,age:number,skill:string){
this.name = name
this.age = age
this.skill = skill
}
public interest(){
console.log('找小姐姐')
}
}
let jspangObj:Jspang = new Jspang('技術胖',18,'web')
jspangObj.interest()
複製程式碼
我作了一個我自己的抽象類,有姓名,有年齡,有技能,然後還有一個函式是興趣。類建立好之後我們就進行了例項化。
現在技術胖要繁衍生息了,跟準備生個兒子(也就是我們說的子類)。那我的兒子一定要比我強啊,他不僅完全繼承了我的基因,還增加了帥氣的屬性和賺錢的本領。
我們看看如何用程式實現。
class JsShuai extends Jspang{
public xingxiang:string = '帥氣'
public zhuangQian(){
console.log('一天賺了一個億')
}
}
let shuai = new JsShuai("技術帥",5,'演講')
shuai.interest()
shuai.zhuangQian()
複製程式碼
extends
關鍵字就是繼承的重點,它相當於我們撲倒女神,小蝌蚪從身體內迸發的一瞬間,所以我們一定要牢記這種感受.....不,是關鍵詞.
但是有一點需要我們注意,TypeScript不支援多重繼承。
類方法的重寫
重寫就是在子類中重寫父類的方法。例如,我的兒子“技術帥”發現興趣愛好是找小姐姐,完成不了“”一天賺一個億“”的目標,它需要多個興趣,開平臺網站。這時候我們就用到了重寫。看下面的列子程式碼:
class JsShuai extends Jspang{
public xingxiang:string = '帥氣'
public interest(){
super.interest()
console.log('建立電商平臺')
}
public zhuangQian(){
console.log('一天賺了一個億')
}
}
複製程式碼
先是繼承了父類的方法,然後通過super關鍵字呼叫了父類的方法,實現了技能的增加。
這節課就到這裡,希望小夥伴們聽過之後都鍛鍊一下生孩子的技能。不是,是寫程式碼的技能,實際寫兩遍。
第14節:物件導向程式設計-介面
作為一個前端,和後端最多的交流就是向後端要介面,而這些介面是如何定義的,有時候我們好像漠不關心。其實前端也有介面的定義,特別如果你要靠著前端技術作一個全棧,那介面的編寫也是必不可少的一項技能。
在通常情況下,介面是用來定義一些規範,使用這些介面,就必須實現按照介面中的規範來走。
在物件導向的語言中,術語interface經常被用來定義一個不包含資料和邏輯程式碼但是用來簽名定義了行為的抽象型別。
認識介面
定義介面的關鍵字是interface
。我們現在就來定義一個介面,這個介面是用來規範丈夫的。
interface Husband {
sex:string
interest:string
}
let myhusband:Husband ={ sex:'男',interest:'看書、作家務'}
console.log(myhusband)
複製程式碼
我們通過介面,定義了一個找老公的介面,並且給他了兩個必選項:性別和興趣愛好.
可選引數的介面
對老公的標準如果我們有一些可選項,這些並不是都需要顯示出來的,在有些情況下,我們只需要傳入部分引數。我們可以使用問好的形式來設定可選引數。
比如現在我們還希望老公的標準,有一條是給我“買包包”,但是這個是隱喻的,不是直接顯示出來的。我們修改我們的介面。
interface Husband {
sex:string
interest:string
maiBaoBao?:Boolean
}
let myhusband:Husband ={ sex:'男',interest:'看書、作家務',maiBaoBao:true}
console.log(myhusband)
複製程式碼
上面的程式碼maiBaoBao
選項就是可選的,可以寫也可以不寫。那撇開程式不談,你寫成為丈夫的機率肯定要大一些。
規範函式型別介面
我們還可以使用介面來規範函式型別的介面,比如現在要找老公這件事,我們規定有一些資源,然後我們需要哪些資源,在函式中進行匹配,最後返回是否匹配成功。
interface SearchMan{
(source:string,subString:string):boolean
}
let mySearch:SearchMan
mySearch = function(source:string,subString:string):boolean{
let flag =source.search(subString)
return (flag != -1)
}
console.log(mySearch('高、富、帥、德','胖')) //false
複製程式碼
介面還可以規範類,但形式都和上滿講的差不多,我就不再這裡浪費小夥伴的時間了。技術胖工作中利用介面就是規範程式標準化使用的,在大團隊中經常使用。但是如果是小團隊,我覺的介面使用的並不多。
第15節:物件導向程式設計-名稱空間
在製作大型應用的時候,為了讓程式更加有層次感和變數之間不互相干擾,我們可以使用名稱空間來構建程式。舉個小例子:比如“德華”這件事,帥哥也有叫德華的,二師兄也有叫德華的。那我們要如何區分那。這對於女孩子選老公來說非常重要啊。
名稱空間的使用
當然名稱空間就是解決這個問題的,名稱空間,又稱內部模組,被用於組織有些具有內在聯絡的特性和物件。我們來看一個例子:
namespace shuaiGe{
export class Dehua{
public name:string = '劉德華'
talk(){
console.log('我是帥哥劉德華')
}
}
}
namespace bajie{
export class Dehua{
public name:string = '馬德華'
talk(){
console.log('我是二師兄馬德華')
}
}
}
let dehua1:shuaiGe.Dehua = new shuaiGe.Dehua()
let dehua2:shuaiGe.Dehua = new bajie.Dehua()
dehua1.talk()
複製程式碼
程式我會在視訊中詳細講解,通過名稱空間我們很好的把程式變的清晰了,各位小姐姐也再也不會劉德華和馬德華傻傻分不清了。
如果你已經學到了這裡,我建議你也學一下ES6的語法,因為Typescript的語法和ES6的有很多都一樣,比如說promise,async/await所以我就不在這裡講述了。有興趣的小夥伴可以學一下。好的,我們下套課程見了。