本文初始编辑地址,源自我的CSDN博客:我的CSDN博客
前言
TypeScript是JavaScript的超集,它的作者是著名的C#之父(名字我忘了)。作为后者的超集,Typescript(以下简称为tsc)拓展了JS,真正的将js从玩具语言变成一种工程语言,一种强类型的语言。并且,tsc的标准是根据每年的ECMA提案来预先实现的,也就是说,tsc兼容未来的ES7,ES8…提前为将来的ES标准打下基础。
学习tsc,不亏!
环境搭建
1 | $ cnpm install -g typescript |
完事,安装tsc的npm包,就是为了使用它自带的功能,将.ts文件编译成.js文件,从而兼容各种平台及浏览器,编译的命令行如下:
1 | $ cd your File_path |
OK,执行完,发现在.ts的同目录下,自动编译完成一个同名的.ts文件。
类型检测
1.基本类型检测
在js中,命名一个变量通常不用指定类型,tsc弥补了这个劣势,加入类型监测,形如:
1 | let a:number = 1; //OK |
2.数组的类型检测:
1 | let arr:number[]=[1,2,3]; //ok 类型+[] |
3.元组类型 Tupe
1 | let X:[number,string]; |
字符串拼接及字符串模板
拼接:跟ES6一样,通过(`
)来实现,【
】为Tab上面的按键。
for eg :
1 | let hi= (` |
字符串模板:提供一种更优雅的书写方式:${ 变量名}
for eg:
1 | let names:string = 'xiaoming'; |
编译后的js文件为:
1 | var names = 'xiaoming'; |
枚举类型
1 | enum flower {a,b,c,d,e,f,g}; //enum关键字,后跟枚举类型的命名 |
Any类型
有时候不希望tsc太严格,对于部分变量或者数据开个后门,就可以声明Any 任意类型。
let不能重复定义,我就用var来演示。
Any类型也可以像数组的第一种定义方法一样,形如:
1 | Array: |
Void类型
void类型表示空。常用在函数返回值,形如:
1 | //注意函数返回值类型检测的写法 |
其实,void包含两种数据类型,就是null和undefind。
触类旁通,其实还有两个类型是null和undefind,如图所示:
如图所示,两个类型不仅自暴自弃,还拉对方下水,形成“你中有我,我中有你”的关系。
类型断言
作用就是清楚的告诉编译器,我知道a是number类型的,不要给我搞事。
写法一:
1 | let a:number =1; |
第二种写法:
Let
来看这样一段代码:
在这个for循环中,有一个setTimeout异步函数,循环5次,打印出的结果是什么呢?
可见,连续打印了5次5,为什么5次都是5 呢?因为setTimeout是一个异步函数,他会等待其他函数执行完,再执行,没有拿到i的最终结果,他不会执行。
究其本质,是因为for循环()中的作用域与{}中的作用域混淆了,如果将这两个作用域独立,那么setTimeout不会等待i的最终执行结果
将上述代码的var i
改为let i
这样,for 循环中的()部分就有了自己独立的块级作用域,所以每次setTimeout执行的时候就不会等待i的最终结果。
因此,代码结果如下图所示:
再来看一个对比:
将var 改为let
可见,两种声明,是一摸一样的输出,为什么呢?
var的声名方式,是因为()和{}基本上可以视为同一作用域,而let的声名方式稍有不同,每次for(let i=0;i<5;i++)
的迭代,都会创建一个新的作用域{},因此,每次的结果照样可以打印出来。
因为这里没有异步函数,即便二者的作用域不同(前者是一个全局作用域,后者是两个块级作用域),输出也是相同的。
总结:使用var或者let,如果当输入环节没有异步函数,无论再怎么变换作用域,那么输出相同,否则,输出不同。
Const
定义了一次,就不能再次定义或者修改赋值。这种定义的方法,用于只读数据,没有修改权限的时候用。
eg:
1 | const a = 1 ; |
结构赋值
普通结构赋值:
函数参数结构赋值:
注意:函数的参数在类型监测的时候,用结构赋值,需要冒号【:】。
数组中的【…】解构语法
输出:
可见,对于未知元素(数组中的成员),默认是对象,当打印输出的时候,会将其当做数组对象来看待。
对象解构
直接结构,这里要注意,新定义的对象中,key键名,一定要与被解构对象的属性名字相同,且不能跳跃式解构。
下图是错误示范:
那么同理,如果在一个方法中返回对象,同样也可以被解构。
如果对象存在嵌套现象,可以使用冒号表达式:
展开
还是使用…语法,进行数组或者对象的浅拷贝。
数组展开,形如:
对象展开,形如:
对象展开时,所有传入的键值对,一旦有重复,按照覆盖原则,后面的value会覆盖前面的。执行顺序是从左到右。
可选参数、默认参数
1 | function test(a:string,b?:string,c="wang"){ |
确定的参数要现在第一个,不能把可选参数写在第一位。
函数断点Yield
在往常的js代码中,不可以人为的暂停或者恢复代码的运行,但是现在有了yield关键字,就可以将函数的执行流程化,从而让我们有条不紊的控制步骤。
1 | function* foo(){ |
箭头函数
作用一:主要用于声明匿名函数,简化代码。
1 | var sum = (a,b)=>a+b |
作用二:消除this指针带来的歧义,优化执行上下文。
1 | function getName (name) { |
这里由于getName()是全局函数,就是window下的一个方法,但是console.log()时,由于window下并没有定义 window.name 属性,因此,打印出来的值是 undefind。
使用箭头函数改造:
1 | function getName (name) { |
For…of循环
for…in 循环对象的下标
1 | var arr = [1, 2, 3, 4]; |
for of 循环对象的key
1 | var arr = [1, 2, 3, 4]; |
forEach 循环循环对象的key值,并且可以循环对象的key值对应的value,但是不能循环数组之外新添加的属性
1 | var arr = [1, 2, 3, 4]; |
总结:for…in循环数组下标。forEach很体面,但是有局限性(不能访问数组外部定义的属性),for…of有点鸡肋,但是胜在使用场景广泛。
interface接口
interface是一种类型,预先定义好一系列的属性的类型,然后供新的对象来使用它。
当然,接口中预先定义的变量,也可以规定/限制函数中的参数:
基于Class的继承
在es3中,javascript的继承只能通过原型链来继承,现在可以通过Class类来继承 。真不愧是“JAVA”script!
访问权限关键字:
public 公共成员。 子类、父类内部都可以访问到。
private 私有成员。只允许在类中访问。
protected 超类的私有成员。但是在子类中仍然可以访问。
构造器Construcor:
1 | //形如: |
在构造器中,相当于新建了一个局部的作用域,在构造器中声明的变量、属性都是局部的,哪怕是在Class内部、构造器之外,也无法访问。
举例说明:
这时候,只要在构造器的name上增加关键字public
,即可在class中全局访问:
类的继承
真的比基于原型链的继承更加优雅和简便。
觉得文章有用?点击下方打赏,鼓励作者更好的写作!