本文是通过学习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 var age:number console .log(age)var age:number = 18 var stature:number = 178.5 var special:number = NaN console .log(age)console .log(stature)console .log(special)var text:string = "what not have a try?" console .log(text)var b:boolean = true var c:boolean = false console .log("---------------------" )enum REN{man = "男人" ,woman = "女人" ,what = "中性" }console .log(REN.what)var t:any = 100 t = "how" t = true console .log(t)
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 ))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 关键字的变量就是一个块级作用域变量function change ( ):void { var thinga:string = 'cat' { let thingb:string = 'dog' console .log(thingb) } console .log(thinga) } change()
当局部变量与全局变量重名的时候,在函数体内是局部变量起作用;当内部声明了和全局的变量同名时,就会出现变量提升的效果,声明语句会提升到函数的第一句。[坑]
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)
引用类型-数组
引用类型有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 x :[string ,number ] x=['hello' ,10 ]
引用类型-字符串
TypeScript中字符串的两种类型
基本类型字符串:由单引号或者双引号括起来的一串字符串。
引用类型字符串:用new 实例化的 String类型。
有了引用类型的字符串就可以给字符串增加一系列方法了。
eg:
let jspang:string = '技术胖' let jspanga:String = new String ("jspang.com" )console .log(jspang)console .log(jspanga)
result:
技术胖 [String : 'jspang.com' ]
基本类型的字符串可以直接使用引用类型的属性和方法。
字符串的长度
let jspang:string = '技术胖' let jspanga:String = new String ("jspang.com" )console .log(jspang.length)console .log(jspanga.length)
字符串常用的方法
查找字符串
从头部查找字符串直接使用indexOf就可以了。
基本语法:str.indexOf(subStr)
let something:string = "清早起来打开窗,心情美美的,我要出去找小姐姐,心情美美的。" let xiaoJieJie:string = "小姐姐" console .log(something.indexOf(xiaoJieJie))
如果我们查找的字符串没有找到,则返回-1。
从字符串尾部开始查找字符串的位置,使用lastIndexOf(subStr)
let something:string = "清早起来打开窗,心情美美的,我要出去找小姐姐,心情美美的。" let xiaoJieJie:string = "小姐姐" console .log(something.lastIndexOf(xiaoJieJie))
需要注意的是,返回的都是字符串的下标。所以返回的值是相同的。并不是返回从后到前的下标位置。
截取字符串
基本语法为: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,'小哥哥' ))
引用类型-日期对象
创建日期对象
日期对象是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)let d1:Date = new Date (1000 )let d2:Date = new Date (2000 )console .log(d1) console .log(d2) 如果传递一个表示日期的字符串,就会生成相对应的日期对象。字符串的格式常用: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 let reg1: RegExp = new RegExp ("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 let reg1:RegExp = /kok-s0s/ let website:string = 'kok-s0s.github.io' let res:boolean = reg1.test(website)console .log(res)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
。
更过关于正则表达式的内容,参考该链接
面向对象编程-类的声明和使用
类是对象具体事物的一个抽象,对象时类的具体表现
类的定义
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) lady.sayhello()
使用readonly修饰符将属性设置为只读,只读属性必须在生命时或者构造函数里被初始化(注意)。
class Man { public readonly sex:string = '男' }var man:Man = new Man()console .log(man.sex)
面向对象编程-继承和重写
类的继承
在使用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()
子类实现 extends
关键字就是继承的重点,但是TypeScript
不支持多重继承。
class JsShuai extends Jspang { public xingxiang:string = '帅气' public zhuangQian ( ) { console .log('一天赚了一个亿' ) } }let shuai = new JsShuai("技术帅" ,5 ,'演讲' ) shuai.interest() shuai.zhuangQian()
类方法的重写
重写就是在子类中重写父类的方法。提供更多种可能性。
class JsShuai extends Jspang { public xingxiang:string = '帅气' public interest ( ) { super .interest() console .log('建立电商平台' ) } public zhuangQian ( ) { console .log('一天赚了一个亿' ) } }
先是继承了父类的方法,然后通过super关键字调用了父类的方法,实现了技能的增加。
面向对象编程-接口
在通常情况下,接口是用来定义一些规范,使用这些接口,就必须实现按照接口中的规范来走。
在面向对象的语言中,术语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('高、富、帅、德' ,'胖' ))
接口可以规范类
面向对象编程-命名空间
在制作大型应用的时候,为了让程序更加有层次感和变量之间不互相干扰,我们可以使用命名空间来构建程序。举个小例子:比如“德华”这件事,帅哥也有叫德华的,二师兄也有叫德华的。那我们要如何区分那。这对于女孩子选老公来说非常重要啊。
当然命名空间就是解决这个问题的,命名空间,又称内部模块,被用于组织有些具有内在联系的特性和对象。我们来看一个例子:
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 ┏━┓