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;
  }
}

 

posted on 2022-02-21 23:42  一名小学生呀  阅读(1173)  评论(0编辑  收藏  举报

导航