TS介紹


JS缺點:

1.舊JS 是弱類型語言,一個變量先后可以保存不同類型的數據(不可靠)

2.舊JS 是解釋執行語言,一邊解釋,一邊執行。一些低級錯誤無法提前檢查和預警

3.舊JS 對對象要求不嚴格,開發人員想怎么寫就怎么寫,不便於大項目協作

 

TypeScript介紹:

是JavaScript 的一個超集(在原有的JS 語言基礎上封裝了一層更嚴格的規范)

支持ECMAScript 6 標准

TypeScript 由微軟開發

設計目的是開發大型應用

 

 

注意: TS 不能被瀏覽器直接執行,但是TS 可以變異成純 JS ,編譯出來的JS 可以運行在任何瀏覽器或 nodejs 上。

TS 的新特性:類型檢查、編譯時錯誤檢查、接口、訪問修飾符、模塊

 

TS的安裝使用:

1. 全局安裝TS 語言的編譯器:npm i -g typescript

2. 用 vscode (vscode需要高版本)打開項目文件夾,右鍵選擇在終端中打開,在終端中輸入:tsc -init   (說明tsc 是ts 語言的編譯器,c 是compile 的意思,編譯)

最后就是在當前項目文件夾中生成了tsconfig.json 文件,其中保存的是將ts 編譯為js 時所需的配置,比如:

-- target:“ES5” 在將ts 文件編譯為js 文件時,編譯為ES5 的版本,兼容更多瀏覽器

-- module:“commenJS” 將來ts 文件中模塊化開發所采用的標准

-- strict:true 將ts 文件編譯js 文件時,自動啟用嚴格模式

接下來就可以新建自己的ts 文件(first.ts):

//規定:a 變量將來只能保存數字類型的值

let a:number = 10
console.log(a)    

再編譯ts 文件為js 文件:打開命令行窗口,輸入tsc first.ts

結果,tsc 編譯器將.ts 文件的內容翻譯為等效的js 文件,保存在ts 文件旁邊的同名first.js文件中:

// first.js

"use strict";
var a = 10;
console.log(a);  // 10

 

以上操作在實際項目中不可能每操作一步就去編譯一次,所以,要配置自動編譯:

在 vscode 中選擇“終端”--“運行生成任務”--“tsc:監視”

配置后只要一自改ts文件,一旦保存就會自動編譯,自動創建js 文件

不輸入命令,運行js 文件:

1.先打開要運行的js 文件

2.點左邊小蟲 + 三角圖標

3.點運行和調試

4.選擇node.js

5.查看執行結果

 

ts中的變量和聲明:

變量 ==》

1.舊的js 是弱類型語言,一個變量先后可以保存不同類型的數據(不可靠)

   今后,只要在ts 中聲明變量,都必須用“:數據類型”來規定

2.標准語法:var 或 const 或 let 變量名:數據類型 = 初始值

   結果:將來這個變量只能保存規定的數據類型

   比如  var a = 10 要換成 let a:number = 10; // 正確

             a = “hello” 報錯:不能將類型“string”分配給類型“number”

 

ts 能夠寫在冒號后的數據類型有哪些呢?

1.基本類型:boolean、number、string 

2.數組:兩種寫法,結果一樣

   2-1.let 數組名:數據類型 [] = [值1,值2,...]   例如 let arr:string[] = ['a','b','c']

   2-2.let 數組名:Array <數據類型> = [值1,值2,...]  

3.any:可以匹配任何數據類型(對於不能確定的數組類型可以使用any定義)例如 var arr2 = ['a',1,true]

 

函數

1.既沒有參數,又沒有返回值的函數,與普通 js 寫法一樣

2.如果函數有返回值

 

3.如果函數有參數 

 

 

 

4.既有形參,又有返回值

 

 

 5.可選參數(一個形參可能有也可能沒有)

  ?表示參數可以沒有。將來如果沒有傳入這個參數值,則參數值默認為undefined

 

 

 6.默認值

 

 

 7.實參值個數不確定

 

 

 

// 無返回值的函數

const intr = () => {
  console.log(`I'm tom`)   // I'm tom
}
intr();

// 帶返回值的函數

const intr2 = ():string => {
  retrun `I'm tom`
}
console.log(intr2())  // I'm tom

// 帶參數的函數

const intr3 = (sname:string,sage:number):string => {
    retrun `I'm ${sname},I'm ${sage}`
}
console.log(intr3('tom',12))   // I'm tom,I'm 12

// 不確定參數

const intr4 = (sname:string,sage?:number):string => {
    if(sage === undefined){
       retrun `I'm ${sname}`
    }else{
       retrun `I'm ${sname},I'm ${sage}`
    }
    retrun `I'm ${sname},I'm ${sage}`
}
console.log(intr4('tom',10))   // I'm tom,I'm 10
console.log(intr4('tom'))     // I'm tom
 
// 默認值的參數

const intr5 = (sname:string,sage:any = '未知') => {
    console.log(`I'm ${sname},年齡:${sage}`)
}
intr5('tom',15)    // I'm tom,年齡:15
intr5('tom')      // I'm tom,年齡:未知

// 求和函數

const add = (...arr:number[]):number => {
  return arr.reduce((box,elem) => box+elem,0)
}
console.log(add(1,2,3))   // 6
console.log(add(1,2,3,4,5))   // 15

 

重載

舊 JS 中,重載只定義一個函數,在函數內根據傳入的參數不同,執行不同的邏輯

function pay(){
  if(arguments.length === 0){
     手機支付
  } else if (arguments.length === 1){
     現金支付
  } else {
     刷卡支付
  }
}
pay()
pay(100)
pay("6553 1234","123456")

TS中:

1.先要定義多個同名函數的聲明,只要形參列表不同即可。但是不要實現函數體

       function 函數名():void;

       function 函數名(形參:數據類型):void;

注意:這里只是不同重載版本的聲明,不包含函數定義

void 代表這個函數沒有返回值

如果函數有返回值,則必須將void 改為返回值的具體類型

2.定義一個可實際執行多種任務的函數支持上方多種重載的情況  

 

 

function pay():void;
function pay(money:number):void;
function pay(cardId:string,pwd:string):void;

//括號里的a和b 也可以寫成(...arr:any[])形式,判斷arr.length打印對應的arr[index]值

function pay(a?:any,b?:any){
  if(a === undefined){
     console.log(`手機支付`)
  }else if(b === undefined){
     console.log(`現金支付,收您${a}元`)
  }else{
     console.log(`刷卡支付,從您卡號:${a} 扣款成功`)
  }
}

pay()   // 手機支付
pay(100) // 現金支付,收您100元
pay('123456')   //刷卡支付,從您卡號:123456 扣款成功

 

CLASS

定義class:

 

 

 

 // 定義一個學生類型

class Student{
  sname:string = '';
  sage:number = 0;
  constructor(sname:string,sage:number){
    this.sname = sname;
    this.sage = sage;
  }  
  intr(){
    console.log(`I'm ${this.sname},I'm ${this.sage}`)
  }
}

var tom = new Student("tom",11) as any;
// ts中默認對象限制對象用中括號來訪問的,所以如果一個對象需要去遍歷,name需要添加as any 防止用中括號讀取屬性值時報錯

console.log(tom);
for(var key in tom){
    console.log(`${key}:${tom[key]}`)
}

tom.intr()

 

兩種類型間繼承

子類型class:

// 類型繼承
// 定義父類型
class Enemy{
  x:number = 0;
  y:number = 0;
  constructor(x:number,y:number){
    this.x = x;
    this.y = y;
  }
  fly(){
    consle.log(`飛到x=${this.x},y=${this.y}位置`)
  }
}
// 定義子類型 class Plane extends Enemy{ score:number
= 0; constructor(x:number,y:number,score:number){ super(x,y); this.score = score } getScore(){ console.log(`擊落敵機,得${this.score}分`) } } var p1 = new Plane(50,100,5) as any;
console.log(p1);
for(var key in p1){ console.log(`${key}:${p1[key]}`) } p1.fly(); p1.getScore();

 

訪問修飾符

class中的所有成員無論在class內,還是在子類型內,還是全局,都可用“this.屬性名” 或 “父對象.屬性名” 方式訪問,沒有限制。

但是有些數據,不想任所有人輕易都知道。舊的js 中就無法控制,所以ts 就產生了訪問修飾符,是專門修飾一個屬性或一個方法的可用范圍的關鍵字(控制訪問的范圍),例如:訪問控制修飾符  ===   屬性名:數據類型 = 初始值

訪問修飾符有3種:

1. public 公有(默認),表示子類型和類外部都可以訪問到的類型成

 

 2. protected 受保護,表示只有父子類型范圍內才能使用,外部不能用

 

 3. private 私有,表示僅class 內可用,子類型和外部都不能用

 

 

// 公有

class Father{
   moneyPublic:string = "爸爸可公開的錢";
   fatherPay(){
      console.log(`爸爸花${this.moneyPublic}買了包煙`)
   }
}
class Son extends Father{
   sonPay(){
     console.log(`孩子花${this.moneyPublic}買了玩具`)
   }
}
var f = new Father();
f.fatherPay();    // 爸爸花爸爸可公開的錢買了包煙
var s = new Son();
s.sonPay();   // 孩子花爸爸可公開的錢買了玩具
console.log(`媽媽花${f.moneyPublic}買了包`)   // 媽媽花爸爸可公開的錢買了包

// 繼承

class Father{
   // 上面因為 public 是默認屬性,所以可以不寫
   protected moneyPublic:string = "爸爸和兒子的小金庫";
   fatherPay(){
      console.log(`爸爸花${this.moneyPublic}買了包煙`)
   }
}
class Son extends Father{
   sonPay(){
     console.log(`孩子花${this.moneyPublic}買了玩具`)
   }
}
var f = new Father();
f.fatherPay();    // 爸爸花爸爸和兒子的小金庫買了包煙
var s = new Son();
s.sonPay();   // 孩子花爸爸和兒子的小金庫買了玩具
console.log(`媽媽花${f.moneyPublic}買了包`)   // 報錯

// 私有

class Father{
   private moneyPublic:string = "爸爸的私房錢";
   fatherPay(){
      console.log(`爸爸花${this.moneyPublic}買了包煙`)
   }
}
class Son extends Father{
   sonPay(){
     console.log(`孩子花${this.moneyPublic}買了玩具`)
   }
}
var f = new Father();
f.fatherPay();    // 爸爸花爸爸的私房錢買了包煙
var s = new Son();
s.sonPay();   // 報錯
console.log(`媽媽花${f.moneyPublic}買了包`)   // 報錯

 

接口

用來規范按照要求實現程序結構,只要希望別人一定按照你的要求實現程序時,都用接口規范

 

 

// 定義學生class 的接口規范,並定義學生class 遵守接口規范

// 上級規定
interface IStudent{
   sname:string;
   sage:number;
   intr():void;
}
// 開發人員
class Student2 implements IStudent{
   sname:string = "";
   sage:number = 0;
   constructor(sname:string,sage:number){
      this.sname = sname;
      this.sage = sage;
   }
   intr():void{
      console.log(`I'm${this.sname},I'm${this.sage}`)
   };
}

var tom2 = new Student2('tom',11);
console.log(tom2);  // {sname:'tom',sage:11}
tom.intr();  // I'm tom,I'm 11

 

模塊化開發

舊JS 中,所有js 文件要幾種引入到html 文件中才能運行,ts 中哪個文件想要使用另一個文件內容,直接引入即可,不用經過任何第三方

 

 

// 只拋出一個文件

interface IStudent{
  sname:string;
  sage:number;
  intr():void;
}
export default IStudent;

// 引入
import ISsudent from "./拋出文件名稱"
class Student implements IStudent{
  sname:string = '';
  sage:number = 0;
  intr():void{
    console.log('打印.....')
  }  
}


// 拋出多個

interface IStudent{
  sname:string;
  sage:number;
  intr():void;
}
class Enemy{
  x:number = 0;
  y:number = 0;
  constructor(x:number,y:number){
    this.x = x;
    this.y = y;
  }
  fly(){
    consle.log(`飛到x = ${this.x},y = ${this.y} 位置`)
  }
}

export {IStudent,Enemy};

// 引入(只引入文件中的其中一個)
import { IStudent } from "./拋出的文件名稱"

class Student implements IStudent{
  sname:string = '';
  sage:number = 0;
  intr():void{
    console.log('打印.....')
  }
}

// 其他文件中引入另一個
import { Enemy } from "./拋出的文件名稱"

class Plane extends Enemy{
  score:number = 0;
  constructor(x:number,y:number,score:number){
    super(x,y);
    this.score = score;
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM