TS学习

本文是通过学习B站一个up主技术胖的视频而记录下的学习过程。

从面向对象开始的教程因为学过了(),所以找了技术胖博客来作为学习资料。

好吧,这个堪称TypeScript的超入门教程,一天时间可以过完。

变量类型

TypeScript最大的一个特点就是变量是强类型的,也就是说在声明变量时,我们必须给他定义一个类型。

TypeScript中的数据类型有:

Undefined :
Number:数值类型;
string : 字符串类型;
Boolean: 布尔类型;
enum:枚举类型;
any : 任意类型,一个牛X的类型;
void:空类型;
Array : 数组类型;
Tuple : 元祖类型;
Null :空类型。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//在js中当你定义了一个变量,但没有给它赋予任何值的时候,它就是Undefined类型。
var age:number
console.log(age)

//Number 可用于表示整数或浮点数
//Infinity:正无穷大
//-Infinity:负无穷大
//NaN:它是Not a Number 的简写,意思就是不是一个数值。如果一个计算结果或者函数的返回值本应该是数值,但是由于种种原因,他不是数字。出现这种状况不会报错,而是把它的结果看成了NaN。
var age:number = 18
var stature:number = 178.5
var special:number = NaN

console.log(age)
console.log(stature)
console.log(special)

//string 单双引号都可以使用
var text:string = "what not have a try?"

console.log(text)

//boolean
var b:boolean = true
var c:boolean = false

//enum 枚举类型 人:男人,女人,中性; 四季
console.log("---------------------")
enum REN{man = "男人",woman = "女人",what = "中性"}
console.log(REN.what)

//any 万能类型
var t:any = 100
t = "how"
t = true
console.log(t)

//null 表示引用类型为空

TypeScript的函数

需要注意的是:

  • 声明(定义)函数必须加 function 关键字;
  • 函数名与变量名一样,命名规则按照标识符规则;
  • 函数参数可有可无,多个参数之间用逗号隔开;
  • 每个参数参数由名字与类型组成,之间用分号隔开;
  • 函数的返回值可有可无,没有时,返回类型为 void;
  • 大括号中是函数体。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function search(age:number):string{
return '找到了' + age + '岁的学生'
}
var age:number = 18
var result:string = search(age)
console.log(result)

//有可选参数的函数
function search(age:number,stature?:string):string{
let yy:string = ""
yy = '找到了' + age + '岁'
if(stature!=undefined){
yy += stature
}
return yy + '的学生'
}
var result:string = search(22,'快乐的')
console.log(result)

//有默认参数的函数
function search(age:number=18,stature:string='很高的'):string{
let yy:string = ""
yy = '找到了' + age + '岁'
if(stature!=undefined){
yy += stature
}
return yy + '的学生'
}
var result:string = search(22,'快乐的')
console.log(result)

//有剩余参数的函数 需求不确定
function search(...xuqiu:string[]):string{
let yy:string = "找到了"
for(let i=0;i<xuqiu.length;++i){
yy += xuqiu[i]
if(i<xuqiu.length-1){
yy += ','
}
}
return yy + '的学生'
}
var result:string = search('22岁','快乐的','无忧的','傻傻的')
console.log(result)

三种函数的定义

  • 函数声明法
    • 函数声明法创建函数是最常用的函数定义法。使用function关键字和函数名去定义一个函数。
  • 函数表达式法
    • 函数表达式法是将一个函数赋值给一个变量,这个变量名就是函数名。通过变量名就可以调用函数了。这种方式定义的函数,必须在定义之后,调用函数。下面例子中等号右边的函数没有函数名,称为匿名函数。
  • 箭头函数
    • 箭头函数是 ES6 中新增的函数定义的新方式,我们的 TypeScript 语言是完全支持 ES6 语法的。箭头函数定义的函数一般都用于回调函数中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//函数声明法
function add(n1:number,n2:number):number{
return n1+n2
}
console.log(add(1,5))

//函数表达式法
var add = function(n1:number,n2:number):number{
return n1+n2
}
console.log(add(1,1))

//箭头函数 ES6
var add = (n1:number,n2:number):number=>{
return n1+n2
}
console.log(add(1,6))

函数中变量的作用域

每个变量都有一个起作用的范围,这个范围就是变量的作用域。在TypeScript语言中变量作用域划分是以函数为标准的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//变量的作用域,依据函数划分

//局部变量
function change():void{
var thing:string = 'cat'
console.log(thing)
}
change()
console.log(thing) 会报错,thing作用域只在change函数中

//全局变量
var thing:string = 'cat'
console.log(thing)
function change():void{
thing = 'dog'
console.log(thing)
}
change()
console.log(thing)

//let关键字

使用let关键字的变量就是一个块级作用域变量

function change():void{
var thinga:string = 'cat'
{
let thingb:string = 'dog'
console.log(thingb)
}
console.log(thinga)
//console.log(thingb) 会报错
}
change()

当局部变量与全局变量重名的时候,在函数体内是局部变量起作用;当内部声明了和全局的变量同名时,就会出现变量提升的效果,声明语句会提升到函数的第一句。[坑]

1
2
3
4
5
6
7
8
9
var yangzi:string = '刘德华'
function zhengXing():void{
console.log('技术胖整形成了'+yangzi+'的样子')
var yangzi:string = '马德华'

console.log('技术胖整形成了'+yangzi+'的样子')
}
zhengXing()
console.log(yangzi)

技术胖整形成了undefined的样子

1
2
3
4
5
6
7
8
9
10
var yangzi:string = '刘德华'
function zhengXing():void{
var yangzi:string
console.log('技术胖整形成了'+yangzi+'的样子')
yangzi = '马德华'

console.log('技术胖整形成了'+yangzi+'的样子')
}
zhengXing()
console.log(yangzi)

引用类型-数组

引用类型有Array(数组),String(字符串),Date(日期对象),RegExp(正则表达式)等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//初始化数组的两种方法
let arr1:number[] //声明一个数值类型的数组
let arr2:Array<string> //声明一个字符串类型的数组

//字面量赋值法
let arr1:number[] = []
let arr2:number[] = [1,2,3,4,5]
let arr3:Array<string> = ['what','什么']
let arr4:Array<boolean> = [true,false,true]

//构造函数赋值法
let arr1:number[] = new Array()
let arr2:number[] = new Array(1,2,3,4,5)
let arr3:Array<string> = new Array('what','什么')
let arr4:Array<boolean> = new Array(true,false,true)

//let arr5:number[] = [1,2,true] 会报错

//元组 有顺序的 一种特殊的数组
let x :[string,number]
x=['hello',10]

引用类型-字符串

TypeScript中字符串的两种类型

  • 基本类型字符串:由单引号或者双引号括起来的一串字符串。
  • 引用类型字符串:用new 实例化的 String类型。

有了引用类型的字符串就可以给字符串增加一系列方法了。

eg:

1
2
3
4
let jspang:string = '技术胖'
let jspanga:String = new String("jspang.com")
console.log(jspang)
console.log(jspanga)

result:

1
2
技术胖
[String: 'jspang.com']

基本类型的字符串可以直接使用引用类型的属性和方法。

字符串的长度

1
2
3
4
let jspang:string = '技术胖'
let jspanga:String = new String("jspang.com")
console.log(jspang.length)
console.log(jspanga.length)

字符串常用的方法

查找字符串

从头部查找字符串直接使用indexOf就可以了。

基本语法:str.indexOf(subStr)

1
2
3
let something:string = "清早起来打开窗,心情美美的,我要出去找小姐姐,心情美美的。"
let xiaoJieJie:string = "小姐姐"
console.log(something.indexOf(xiaoJieJie)) //19

如果我们查找的字符串没有找到,则返回-1。

从字符串尾部开始查找字符串的位置,使用lastIndexOf(subStr)

1
2
3
let something:string = "清早起来打开窗,心情美美的,我要出去找小姐姐,心情美美的。"
let xiaoJieJie:string = "小姐姐"
console.log(something.lastIndexOf(xiaoJieJie)) //19

需要注意的是,返回的都是字符串的下标。所以返回的值是相同的。并不是返回从后到前的下标位置。

截取字符串

基本语法为:str.substring(startIndex,[endIndex])

参数 startIndex 表示开始下标,endIndex 表示结束下标,endIndex 参数是可选的。

该方法的作用是从指定的开始下标开始截取字符串,截取到 endIndex 的下标之前,如果没有 endIndex,则截取到字符串结束。

1
2
3
4
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 子串会被替换掉。

1
2
3
let something:string = "清早起来打开窗,心情美美的,我要出去找小姐姐,心情美美的。"
let xiaoJieJie:string = "小姐姐"
console.log(something.replace(xiaoJieJie,'小哥哥'))

引用类型-日期对象

创建日期对象

日期对象是Date的实例,可以使用构造函数的方法进行创建。并且构造函数中可以传递多种类型的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//不传递任何参数
Date()构造函数将根据当前日期和时间创建一个Date对象。但不一定是中国时区。

let d:Date = new Date()
console.log(d)

//传递一个整数,这个整数代表的是距离1970-01-01 00:00:00的毫秒数
let d1:Date = new Date(1000)
let d2:Date = new Date(2000)
console.log(d1) //1970-01-01T00:00:01.000Z
console.log(d2) //1970-01-01T00:00:02.000Z

//传递一个字符串
如果传递一个表示日期的字符串,就会生成相对应的日期对象。字符串的格式常用: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)

//传递表示年月日时分秒的变量
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之间的整数。

引用类型-正则表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//RegExp      string

//构造函数声明法 采用new关键字 可传一个或多个参数
//一个是字符串描述,另一个是修饰符。
//比如g是全局修饰符,i是忽略大小写,m是多行模式。
let reg1: RegExp = new RegExp("kok-s0s") //表示字符串规则里含有kok-s0s
console.log(reg1)
let reg2: RegExp = new RegExp("kok-s0s", 'gi')
console.log(reg2)

//字面量声明法
let reg3:RegExp = /kok-s0s/
let reg4: RegExp = /kok-s0s/gi

//test(string)
let reg1:RegExp = /kok-s0s/
let website:string = 'kok-s0s.github.io'
let res:boolean = reg1.test(website)
console.log(res)

//exec(string)
let reg1: RegExp = /kok-s0s/
let website: string = 'kok-s0s.github.io'
let res: boolean = reg1.test(website)
console.log(reg1.exec(website))

RegExp中的常用方法
RegExp对象包含两个方法:test( )和exec( ),功能基本相似,用于测试字符串匹配。

  • test(string) :在字符串中查找是否存在指定的正则表达式并返回布尔值,如果存在则返回 true,不存在则返回 false
  • exec(string) : 用于在字符串中查找指定正则表达式,如果 exec() 方法执行成功,则返回包含该查找字符串的相关信息数组。如果执行失败,则返回 null

更过关于正则表达式的内容,参考该链接

面向对象编程-类的声明和使用

类是对象具体事物的一个抽象,对象时类的具体表现

类的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

class People {
name:string
age:number
constructor(name:string,age:number) {
this.name = name
this.age = age
}
say() {
console.log('hello!')
}
}

let lady:People = new People('kok-s0s',20)
console.log(lady)
lady.say()

面向对象编程-修饰符

TypeScript语言和Java还有C#很像(因为我只会这两个面向对象的语言),类中属性的访问可以用访问修饰符来进行限制。访问修饰符分为:public、protected、private。

  • public:公有修饰符,可以在类内或者类外使用public修饰的属性或者行为,默认修饰符。
  • protected:受保护的修饰符,可以本类和子类中使用protected修饰的属性和行为。
  • private : 私有修饰符,只可以在类内使用private修饰的属性和行为。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class People {
public sex: string
protected name: string
private age: number
constructor(sex:string,name: string, age: number) {
this.sex = sex
this.name = name
this.age = age
}
public sayhello() {
console.log('hello!')
}
protected saygood() {
console.log('well done!')
}
}

var lady:People = new People('女','斋藤飞鸟',19)

console.log(lady)
console.log(lady.sex)
// console.log(lady.name) 报错
// console.log(lady.age) 报错
lady.sayhello()
// lady.saygood() 报错

使用readonly修饰符将属性设置为只读,只读属性必须在生命时或者构造函数里被初始化(注意)。

1
2
3
4
5
6
7
//只读修饰符 readonly
class Man {
public readonly sex:string = '男'
}
var man:Man = new Man()
console.log(man.sex)
// man.sex = '女' 会报错,无法修改

面向对象编程-继承和重写

类的继承

在使用TypeScript这门语言时,一个最重要基本功就是面向对象编程,那对类的扩展就变的格外重要,扩展经常使用的手段就是继承。

继承:允许我们创建一个类(子类),从已有的类(父类)上继承所有的属性和方法,子类可以新建父类中没有的属性和方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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()

子类实现 extends关键字就是继承的重点,但是TypeScript不支持多重继承。

1
2
3
4
5
6
7
8
9
10
class JsShuai extends Jspang{
public xingxiang:string = '帅气'
public zhuangQian(){
console.log('一天赚了一个亿')
}
}

let shuai = new JsShuai("技术帅",5,'演讲')
shuai.interest()
shuai.zhuangQian()

类方法的重写

重写就是在子类中重写父类的方法。提供更多种可能性。

1
2
3
4
5
6
7
8
9
10
class JsShuai extends Jspang{
public xingxiang:string = '帅气'
public interest(){
super.interest()
console.log('建立电商平台')
}
public zhuangQian(){
console.log('一天赚了一个亿')
}
}

先是继承了父类的方法,然后通过super关键字调用了父类的方法,实现了技能的增加。

面向对象编程-接口

在通常情况下,接口是用来定义一些规范,使用这些接口,就必须实现按照接口中的规范来走。

在面向对象的语言中,术语interface经常被用来定义一个不包含数据和逻辑代码但是用来签名定义了行为的抽象类型。

认识接口

定义接口的关键字是interface。我们现在就来定义一个接口,这个接口是用来规范丈夫的。

1
2
3
4
5
6
interface Husband {
sex:string
interest:string
}
let myhusband:Husband ={ sex:'男',interest:'看书、作家务'}
console.log(myhusband)

可选参数的接口

对老公的标准如果我们有一些可选项,这些并不是都需要显示出来的,在有些情况下,我们只需要传入部分参数。我们可以使用问好的形式来设置可选参数。

比如现在我们还希望老公的标准,有一条是给我“买包包”,但是这个是隐喻的,不是直接显示出来的。我们修改我们的接口。

1
2
3
4
5
6
7
interface Husband {
sex:string
interest:string
maiBaoBao?:Boolean
}
let myhusband:Husband ={ sex:'男',interest:'看书、作家务',maiBaoBao:true}
console.log(myhusband)

上面的代码maiBaoBao选项就是可选的,可以写也可以不写。

规范函数类型接口

我们还可以使用接口来规范函数类型的接口,比如现在要找老公这件事,我们规定有一些资源,然后我们需要哪些资源,在函数中进行匹配,最后返回是否匹配成功。

1
2
3
4
5
6
7
8
9
10
11
12
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

接口可以规范类

面向对象编程-命名空间

在制作大型应用的时候,为了让程序更加有层次感和变量之间不互相干扰,我们可以使用命名空间来构建程序。举个小例子:比如“德华”这件事,帅哥也有叫德华的,二师兄也有叫德华的。那我们要如何区分那。这对于女孩子选老公来说非常重要啊。

当然命名空间就是解决这个问题的,命名空间,又称内部模块,被用于组织有些具有内在联系的特性和对象。我们来看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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:bajie.Dehua = new bajie.Dehua()
dehua1.talk()
dehua2.talk()

我是帅哥刘德华
我是二师兄马德华

按照这个视频的说法,我是该去学些ES6的知识了。

⚔🏹( o=^•ェ•)o ┏━┓


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!