0


菜鸟教程笔记:TypeScript

一.TypeScript基础语法

运行ts程序

1.在ts文件中:Runoob.ts

const hello :string="Hello World!"console.log(hello)

2.通过tsc命令编译

tsc Runoob.ts

3.得到js代码:Runoob.js

var hello ="Hello World!";
console.log(hello);

4.使用node来执行js代码

$ node Runoob.js
Hello World

我们可以同时编译多个ts文件:

tsc file1.ts file2.ts file3.ts

在这里插入图片描述

tsc常用编译参数:

在这里插入图片描述

空白和换行

ts会忽略 空格 , 制表符 , 换行符

区分大小写

分号是可选的,可以不写,但建议使用

ts与面向对象

理解:对现实世界理解和抽象的方法
面向对象有两个概念:对象和类
对象:类的一个实例,有状态和行为。
类:是一个模板,里面包含一类对象的行为,状态
方法:类的操作的实现步骤

面向对象编程实例:

编译前ts的代码:
classSite{name():void{console.log("Runoob")}}var obj =newSite(); 
obj.name();
编译后js的代码:
var Site =/** @class */(function(){functionSite(){}Site.prototype.name=function(){
            console.log("Runoob");};return Site;}());var obj =newSite();
obj.name();

二.TS的基础类型

在这里插入图片描述
在这里插入图片描述

Any类型

在这里插入图片描述

1.跳过类型检查

let x:any=1;// 数字类型
x ='I am who I am';// 字符串类型
x =false;// 布尔类型

2.允许在编译时可选择地包含或移除类型检查

let x:any=4;
x.ifItExists();// 正确,ifItExists方法在运行时可能存在,但这里并不会检查
x.toFixed();// 正确

3.定义存储数组

let arrayList:any[]=[1,false,'fine'];
arrayList[1]=100;

null和Undefined

null

表示:1.什么都没有
2.空对象引用
3.用typeof 返回 object

undefined

表示:1.一个没有设置值的变量
2.用typeof 会返回 undefined
3.null和undefined 是任何类型的子类型,所以可以赋值给其他类型,但在严格空检验(–stricNullChecks)下,只能赋给void或其本身对应的类型

// 启用 --strictNullCheckslet x:number;
x =1;// 编译正确
x =undefined;// 编译错误
x =null;// 编译错误

never类型

表示:1.代表不会出现的值
2.声明了never只能被never类型所赋值
是其他类型(包括null和nudefined)的子类型,

let x:never;let y:number;// 编译错误,数字类型不能转为 never 类型
x =123;// 运行正确,never 类型可以赋值给 never类型
x =(()=>{thrownewError('exception')})();// 运行正确,never 类型可以赋值给 数字类型
y =(()=>{thrownewError('exception')})();// 返回值为 never 的函数可以是抛出异常的情况functionerror(message:string):never{thrownewError(message);}// 返回值为 never 的函数可以是无法被执行到的终止点的情况functionloop():never{while(true){}}

三.变量声明

用于引用计算机内存地址
变量命名规则:

  • 只能包含_和$

var [变量名] : [类型] = 值;

变量作用域

  • 全局作用域
  • 类作用域:类变量在类的方法外,可通过类的对象访问。也可以是静态的,静态变量可以通过类名直接访问—class.valname
  • 局部作用域

ts的代码

var global_num =12// 全局变量classNumbers{ 
   num_val =13;// 实例变量static sval =10;// 静态变量storeNum():void{var local_num =14;// 局部变量}}console.log("全局变量为: "+global_num)console.log(Numbers.sval)// 静态变量var obj =newNumbers();console.log("实例变量: "+obj.num_val)

tsc编译的js代码

var global_num =12;// 全局变量var Numbers =/** @class */(function(){functionNumbers(){this.num_val =13;// 实例变量}Numbers.prototype.storeNum=function(){var local_num =14;// 局部变量};
    Numbers.sval =10;// 静态变量return Numbers;}());
console.log("全局变量为: "+ global_num);
console.log(Numbers.sval);// 静态变量var obj =newNumbers();
console.log("实例变量: "+ obj.num_val);

四.运算符

位运算符

在这里插入图片描述

var a:number=2;// 二进制 10 var b:number=3;// 二进制 11var result; 
        
result =(a & b);console.log("(a & b) => ",result)
            
result =(a | b);console.log("(a | b) => ",result)  
        
result =(a ^ b);console.log("(a ^ b) => ",result);
    
result =(~b);console.log("(~b) => ",result);
 
result =(a << b);console.log("(a << b) => ",result); 
 
result =(a >> b);console.log("(a >> b) => ",result);
 
result =(a >>>1);console.log("(a >>> 1) => ",result);

三元运算符

Test ? expr1 : expr2

var num:number=-2var result = num >0?"大于 0":"小于 0,或等于 0"console.log(result)

类型运算符

typeof 运算符

返回:操作数的数据类型

var num =12console.log(typeof num);//输出结果: number

instanceof

判断对象是否与预期的类型相同

字符串运算符:连接运算符(+)

var msg:string="RUNOOB"+".COM"console.log(msg)

五.循环

  1. for … in …
  2. for … of …
  3. forEach
  4. every
  5. some

1.for… in … 循环

用于一组值的集合或列表进行迭代

for(var val in list){//语句 }

实例

var j:any;var n:any="a b c"for(j in n){console.log(n[j])}

2.for…of …

for…of 允许遍历 Arrays(数组), Strings(字符串), Maps(映射), Sets(集合)等可迭代的数据结构等。

let someArray =[1,"string",false];for(let entry of someArray){console.log(entry);// 1, "string", false}

3.forEach

js循环语法:forEach,every,some
ts:因为forEach在iteration中是无法返回的,所以用every和some来取代foreach

let list =[4,5,6];
list.forEach((val, idx, array)=>{// val: 当前值// idx:当前index// array: Array});

4.every

let list =[4,5,6];
list.every((val, idx, array)=>{// val: 当前值// idx:当前index// array: Arrayreturntrue;// Continues// Return false will quit the iteration});

六.函数

函数返回值

// 函数定义functiongreet():string{// 返回一个字符串return"Hello World"}functioncaller(){var msg =greet()// 调用 greet() 函数 console.log(msg)}// 调用函数caller()

带参数函数

functionadd(x:number, y:number):number{return x + y;}console.log(add(1,2))

可选参数和默认参数

用?修饰,即可用可不用

functionbuildName(firstName:string, lastName?:string){if(lastName)return firstName +" "+ lastName;elsereturn firstName;}let result1 =buildName("Bob");// 正确let result2 =buildName("Bob","Adams","Sr.");// 错误,参数太多了let result3 =buildName("Bob","Adams");// 正确

默认参数

参数不能同时设置为可选和默认

functioncalculate_discount(price:number,rate:number=0.50){var discount = price * rate;console.log("计算结果: ",discount);}calculate_discount(1000)calculate_discount(1000,0.30)

剩余参数

以…为前缀,当传入的参数不确定时使用

functionbuildName(firstName:string,...restOfName:string[]){return firstName +" "+ restOfName.join(" ");}let employeeName =buildName("Joseph","Samuel","Lucas","MacKinzie");

匿名函数

函数表达式:将匿名函数赋值给一个变量
格式:
**

var res = function( [arguments] ) { ... }

**

varres=function(a:number,b:number){return a*b;};console.log(res(12,2))

匿名函数自调用

自己执行自己,不会变量提升,运行完就释放内存

(function(){var x ="Hello!!";console.log(x)})()

构造函数

利用new Function来定义函数

var res = new Function ([arg1[, arg2[, …argN]],] functionBody)

var myFunction =newFunction("a","b","return a * b");var x =myFunction(4,3);console.log(x);

递归函数

函数内调用函数本身

functionfactorial(number){if(number<=0){// 停止执行return1;}else{return(number*factorial(number-1));// 调用自身}};console.log(factorial(6));// 输出 720

Lambda函数

  • ()是可选的
  • 无参数时可以设置空括号
  • 不指定函数的参数类型,通过函数内来推断参数类型

也被称为箭头函数,,比较简洁,,建议常用

( [param1, parma2,…param n] )=>statement;

varfoo=(x:number)=>10+ x 
console.log(foo(100))//输出结果为 110

()是可选的

vardisplay= x =>{console.log("输出为 "+x)}display(12)

无参数时可以设置空括号

vardisp=()=>{console.log("Function invoked");}disp();

不指定函数的参数类型,通过函数内来推断参数类型

varfunc=(x)=>{if(typeof x=="number"){console.log(x+" 是一个数字")}elseif(typeof x=="string"){console.log(x+" 是一个字符串")}}func(12)func("Tom")

函数重载

方法名相同,而参数不同

functiondisp(s1:string):void;functiondisp(n1:number,s1:string):void;functiondisp(x:any,y?:any):void{console.log(x);console.log(y);}disp("abc")disp(1,"xyz");

七.Number

是一个原始类
var num = new Number(value);
注意: 如果一个参数值不能转换为一个数字将返回 NaN (非数字值)。
在这里插入图片描述

console.log("TypeScript Number 属性: ");console.log("最大值为: "+ Number.MAX_VALUE);console.log("最小值为: "+ Number.MIN_VALUE);console.log("负无穷大: "+ Number.NEGATIVE_INFINITY);console.log("正无穷大:"+ Number.POSITIVE_INFINITY);

NaN实例

var month =0if( month<=0|| month >12){ 
    month = Number.NaNconsole.log("月份是:"+ month)}else{console.log("输入月份数值正确。")}//输出结果:月份是:NaN

prototype实例

functionemployee(id:number,name:string){this.id = id 
    this.name = name 
}var emp =newemployee(123,"admin") 
employee.prototype.email ="[email protected]"console.log("员工号: "+emp.id)console.log("员工姓名: "+emp.name)console.log("员工邮箱: "+emp.email)

在这里插入图片描述
在这里插入图片描述

八.String(字符串)

用于处理文本

String对象属性

在这里插入图片描述

方法省略

八.Array(数组)

如果在声明的时候没有设置类型,默认为any类型

声明时直接初始化

var nums:number[]=[1,2,3,4]console.log(nums[0]);console.log(nums[1]);console.log(nums[2]);console.log(nums[3]);

Array

可以用其创建数组,,比较冷门
(参数一,参数二)
(数组大小的数值,初始化的数组列表使用,分隔符)

var arr_names:number[]=newArray(4)for(var i =0; i<arr_names.length; i++){ 
        arr_names[i]= i *2console.log(arr_names[i])}
var sites:string[]=newArray("Google","Runoob","Taobao","Facebook")for(var i =0;i<sites.length;i++){console.log(sites[i])}

数组解构

var arr:number[]=[12,13]var[x,y]= arr // 将数组的两个元素赋值给变量 x 和 yconsole.log(x)console.log(y)

数组迭代

var j:any;var nums:number[]=[1001,1002,1003,1004]for(j in nums){console.log(nums[j])}

多维数组

在这里插入图片描述

var multi:number[][]=[[1,2,3],[23,24,25]]console.log(multi[0][0])console.log(multi[0][1])console.log(multi[0][2])console.log(multi[1][0])console.log(multi[1][1])console.log(multi[1][2])

作为参数传递给函数

var sites:string[]=newArray("Google","Runoob","Taobao","Facebook")functiondisp(arr_sites:string[]){for(var i =0;i<arr_sites.length;i++){console.log(arr_sites[i])}}disp(sites);

作为函数的返回值

functiondisp():string[]{returnnewArray("Google","Runoob","Taobao","Facebook");}var sites:string[]=disp()for(var i in sites){console.log(sites[i])}

九.Map对象

保存键值对,并且能够记住键的原始插入顺序

创建Map

let myMap = new Map();

初始化Map,可以以数组的格式来传入键值对

let myMap =newMap([["key1","value1"],["key2","value2"]]);

相关的函数与属性

在这里插入图片描述

let nameSiteMapping =newMap();// 设置 Map 对象
nameSiteMapping.set("Google",1);
nameSiteMapping.set("Runoob",2);
nameSiteMapping.set("Taobao",3);// 获取键对应的值console.log(nameSiteMapping.get("Runoob"));// 2// 判断 Map 中是否包含键对应的值console.log(nameSiteMapping.has("Taobao"));// trueconsole.log(nameSiteMapping.has("Zhihu"));// false// 返回 Map 对象键/值对的数量console.log(nameSiteMapping.size);// 3// 删除 Runoobconsole.log(nameSiteMapping.delete("Runoob"));// trueconsole.log(nameSiteMapping);// 移除 Map 对象的所有键/值对
nameSiteMapping.clear();// 清除 Mapconsole.log(nameSiteMapping);

使用ES6编译

tsc --target es6 test.ts

迭代Map

Map对象中的元素是按顺序插入的,每一次迭代返回[key,value]数组,建议使用for…of

let nameSiteMapping =newMap();
 
nameSiteMapping.set("Google",1);
nameSiteMapping.set("Runoob",2);
nameSiteMapping.set("Taobao",3);// 迭代 Map 中的 keyfor(let key of nameSiteMapping.keys()){console.log(key);}// 迭代 Map 中的 valuefor(let value of nameSiteMapping.values()){console.log(value);}// 迭代 Map 中的 key => valuefor(let entry of nameSiteMapping.entries()){console.log(entry[0], entry[1]);}// 使用对象解析for(let[key, value]of nameSiteMapping){console.log(key, value);}

使用ES6编译

tsc --target es6 test.ts

十.元组

于数组相反,允许存储不同类型的元素,可以作为参数传递给函数

格式:var tuple_name = [value1,value2,value3,…value n]

创建元组

声明一个元组并初始化

var mytuple =[10,"Runoob"];

访问元组

var mytuple =[10,"Runoob"];// 创建元组console.log(mytuple[0])console.log(mytuple[1])

元组运算

  • push() 向元组添加元素至最后
  • pop(): 从元组中移除最后一个元素,并返回移除的元素
var mytuple =[10,"Hello","World","typeScript"];console.log("添加前元素个数:"+mytuple.length)// 返回元组的大小
 
mytuple.push(12)// 添加到元组中console.log("添加后元素个数:"+mytuple.length)console.log("删除前元素个数:"+mytuple.length)console.log(mytuple.pop()+" 元素从元组中删除")// 删除并返回删除的元素console.log("删除后元素个数:"+mytuple.length)

更新元组

元组是可变的

var mytuple =[10,"Runoob","Taobao","Google"];// 创建一个元组console.log("元组的第一个元素为:"+ mytuple[0])// 更新元组元素
mytuple[0]=121console.log("元组中的第一个元素更新为:"+ mytuple[0])

解构元组

var a =[10,"Runoob"]var[b,c]= a 
console.log( b )console.log( c )

十一.联合类型

管道( | )将变量设置多种类型

var val:string|number 
val =12console.log("数字为 "+ val) 
val ="Runoob"console.log("字符串为 "+ val)

将联合类型作为函数参数使用

functiondisp(name:string|string[]){if(typeof name =="string"){console.log(name)}else{var i;for(i =0;i<name.length;i++){console.log(name[i])}}}disp("Runoob")console.log("输出数组....")disp(["Runoob","Google","Taobao","Facebook"])

联合类型数组

var arr:number[]|string[];var i:number; 
arr =[1,2,4]console.log("**数字数组**")for(i =0;i<arr.length;i++){console.log(arr[i])}  
 
arr =["Runoob","Google","Taobao"]console.log("**字符串数组**")for(i =0;i<arr.length;i++){console.log(arr[i])}

一十二.接口

  • 是一系列抽象方法的声明
  • 一些方法特征的集合
  • 这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。

格式:interface interface_name {
}

interfaceIPerson{ 
    firstName:string, 
    lastName:string,sayHi:()=>string}var customer:IPerson ={ 
    firstName:"Tom",
    lastName:"Hanks", 
    sayHi:():string=>{return"Hi there"}}console.log("Customer 对象 ")console.log(customer.firstName)console.log(customer.lastName)console.log(customer.sayHi())var employee:IPerson ={ 
    firstName:"Jim",
    lastName:"Blakes", 
    sayHi:():string=>{return"Hello!!!"}}console.log("Employee  对象 ")console.log(employee.firstName)console.log(employee.lastName)

联合类型和接口

在接口中使用联合类型

interfaceRunOptions{ 
    program:string; 
    commandline:string[]|string|(()=>string);}// commandline 是字符串var options:RunOptions ={program:"test1",commandline:"Hello"};console.log(options.commandline)// commandline 是字符串数组
options ={program:"test1",commandline:["Hello","World"]};console.log(options.commandline[0]);console.log(options.commandline[1]);// commandline 是一个函数表达式
options ={program:"test1",commandline:()=>{return"**Hello World**";}};var fn:any= options.commandline;console.log(fn());

接口和数组

接口中我们可以将数组的索引值元素设置为不同类型,索引值可以是数字字符串

interfacenamelist{[index:number]:string}// 类型一致,正确var list2:namelist =["Google","Runoob","Taobao"]// 错误元素 1 不是 string 类型// var list2:namelist = ["Runoob",1,"Taobao"]

接口继承

接口通过其他接口来拓展自己

  • 接口继承多个接口
  • 使用关键字extends

单继承实例

interfacePerson{ 
   age:number}interfaceMusicianextendsPerson{ 
   instrument:string}var drummer =<Musician>{}; 
drummer.age =27 
drummer.instrument ="Drums"console.log("年龄:  "+drummer.age)console.log("喜欢的乐器:  "+drummer.instrument)

多继承实例

interfaceIParent1{ 
    v1:number}interfaceIParent2{ 
    v2:number}interfaceChildextendsIParent1, IParent2 {}var Iobj:Child ={ v1:12, v2:23}console.log("value 1: "+Iobj.v1+" value 2: "+Iobj.v2)

十三.类

描述所创建对象共同的属性和方法
支持类和接口
注意构造函数的参数名与字段名相同

classCar{// 字段 
    engine:string;// 构造函数 constructor(engine:string){this.engine = engine 
    }// 方法 disp():void{console.log("发动机为 :   "+this.engine)}}

创建实例化对象

类实例化时会调用构造函数
var obj = new Car(“Engine 1”)

classCar{// 字段
   engine:string;// 构造函数constructor(engine:string){this.engine = engine 
   }// 方法disp():void{console.log("函数中显示发动机型号  :   "+this.engine)}}// 创建一个对象var obj =newCar("XXSY1")// 访问字段console.log("读取发动机型号 :  "+obj.engine)// 访问方法
obj.disp()

类的继承

  • 子类不能继承父类的私有成员(方法和属性)
  • 支持多重继承,但一次只能继承一个类
classShape{ 
   Area:numberconstructor(a:number){this.Area = a 
   }}classCircleextendsShape{disp():void{console.log("圆的面积:  "+this.Area)}}var obj =newCircle(223); 
obj.disp()

继承类的方法重写

  • 类继承后,子类可以对父类的方法重写
  • super 是对父类的直接引用,可以调用父类的属性和方法
classPrinterClass{doPrint():void{console.log("父类的 doPrint() 方法。")}}classStringPrinterextendsPrinterClass{doPrint():void{super.doPrint()// 调用父类的函数console.log("子类的 doPrint()方法。")}}

static 关键字

  • 定义类的数据成员(属性和方法)为静态的
  • 静态成员可以直接通过类名调用
classStaticMem{static num:number;staticdisp():void{console.log("num 值为 "+ StaticMem.num)}} 
 
StaticMem.num =12// 初始化静态变量
StaticMem.disp()// 调用静态方法

instanceof运算符

判断是否是指定类型的

classPerson{}var obj =newPerson()var isPerson = obj instanceofPerson;console.log("obj 对象是 Person 类实例化来的吗? "+ isPerson);

访问控制修饰符

作用:对类,变量,方法,构造方法进行保护

  • Public
  • protected:只允许其自身和子类访问
  • private:只能自身访问
classEncapsulate{ 
   str1:string="hello"private str2:string="world"}var obj =newEncapsulate()console.log(obj.str1)// 可访问 console.log(obj.str2)// 编译错误, str2 是私有的

类和接口

  • 类可以实现接口
  • 使用关键字implements
  • 将interest字段作为类的属性使用
interfaceILoan{ 
   interest:number}classAgriLoanimplementsILoan{ 
   interest:number 
   rebate:numberconstructor(interest:number,rebate:number){this.interest = interest 
      this.rebate = rebate 
   }}var obj =newAgriLoan(10,1)console.log("利润为 : "+obj.interest+",抽成为 : "+obj.rebate )

十四.对象

对象:是一组包含键值对的实例。值可以是标量,数组,函数,对象

var object_name ={ 
    key1:"value1",// 标量
    key2:"value",key3:function(){// 函数}, 
    key4:["content1","content2"]//集合}

类型模板

var sites ={
    site1:"Runoob",
    site2:"Google",sayHello:function(){}// 类型模板};
sites.sayHello=function(){//对象中添加方法console.log("hello "+ sites.site1);};
sites.sayHello();

对象作为参数传递给函数

var sites ={ 
    site1:"Runoob", 
    site2:"Google",};varinvokesites=function(obj:{ site1:string, site2 :string}){console.log("site1 :"+obj.site1)console.log("site2 :"+obj.site2)}invokesites(sites)

鸭子类型

关注行为,不关注类型

interfaceIPoint{ 
    x:number 
    y:number}functionaddPoints(p1:IPoint,p2:IPoint):IPoint {var x = p1.x + p2.x 
    var y = p1.y + p2.y 
    return{x:x,y:y}}// 正确var newPoint =addPoints({x:3,y:4},{x:5,y:1})// 错误 var newPoint2 =addPoints({x:1},{x:4,y:3})

十五.命名空间

  • 解决重名问题
  • 用namespace来定义
  • 互不干扰
  • 如果命名空间中的类和接口,需要外部调用,export
  • 引用一个单独的TS,应使用///
/// <reference path = "SomeFileName.ts" />
namespace SomeNameSpaceName {exportinterfaceISomeInterfaceName{}exportclassSomeClassName{}}

实例

IShape.ts

namespace Drawing {exportinterfaceIShape{draw();}}

Circle.ts

/// <reference path = "IShape.ts" /> namespace Drawing {exportclassCircleimplementsIShape{publicdraw(){console.log("Circle is drawn");}}}

Triangle.ts

/// <reference path = "IShape.ts" /> namespace Drawing {exportclassTriangleimplementsIShape{publicdraw(){console.log("Triangle is drawn");}}}

TestShape.ts

/// <reference path = "IShape.ts" />   /// <reference path = "Circle.ts" /> /// <reference path = "Triangle.ts" />  functiondrawAllShapes(shape:Drawing.IShape){ 
    shape.draw();}drawAllShapes(newDrawing.Circle());drawAllShapes(newDrawing.Triangle());

使用tsc命令编译

tsc --out app.js TestShape.ts 

使用node查看输出结果

$ node app.js
Circle is drawn
Triangle is drawn

嵌套命名空间

Invoice.ts

namespace Runoob {exportnamespace invoiceApp {exportclassInvoice{publiccalculateDiscount(price:number){return price *.40;}}}}

Invoice Test.ts

/// <reference path = "Invoice.ts" />var invoice =newRunoob.invoiceApp.Invoice();console.log(invoice.calculateDiscount(500));

使用tsc编译

tsc --out app.js InvoiceTest.ts

使用node来查看输出结果

$ node app.js
200

十六.模块

作用:

  • 更快的更换代码
  • 模块里的东西外部是不可见的,是局部作用域,非全局作用域
  • 通过import 和export 建立
  • 模块使用模块加载器去导入其他的模块
  • 运行时:模块加载器的作用是下载这个模块的所有依赖

export 模块导出

// 文件名 : SomeInterface.ts exportinterfaceSomeInterface{// 代码部分}

在另一个文件中使用import导入

import someInterfaceRef =require("./SomeInterface");

实例

IShape.ts

/// <reference path = "IShape.ts" /> exportinterfaceIShape{draw();}

Circle.ts

import shape =require("./IShape");exportclassCircleimplementsshape.IShape {publicdraw(){console.log("Cirlce is drawn (external module)");}}

Triangle.ts

import shape =require("./IShape");exportclassTriangleimplementsshape.IShape {publicdraw(){console.log("Triangle is drawn (external module)");}}

TestShape.ts

import shape =require("./IShape");import circle =require("./Circle");import triangle =require("./Triangle");functiondrawAllShapes(shapeToDraw: shape.IShape){
   shapeToDraw.draw();}drawAllShapes(newcircle.Circle());drawAllShapes(newtriangle.Triangle());

使用tsc命令编译

tsc --module amd TestShape.ts 

本文转载自: https://blog.csdn.net/ACBYCL/article/details/126447267
版权归原作者 ACBYCL 所有, 如有侵权,请联系我们删除。

“菜鸟教程笔记:TypeScript”的评论:

还没有评论