什么是JavaScript?
JavaScript是由ECMAScript、DOM、BOM组成。
- ECMAScript 描述了JS的语法和基本对象,是一种标准
- DOM 文档对象模型(Document Object Model)
- BOM 浏览器对象模型(Browser Object Model)
什么是TypeScript?
TypeScript是Microsoft开发和维护的一种面向对象的编程语言。
TypeScript是JavaScript的超集,包含了JavaScript的所有元素,扩展了JavaScript的语法。
TypeScript的特点
- 增加了静态类型、类、模块、接口和类型注解
- 一般用于大型项目,易于维护
TS与JS的差异
- TS是JS的扩展,主要在核心语言方面和类概念的模塑方面
- JS可以在无需任何修改的情况下与TS一同工作,也可以将TS转换成JS
- TS通过类型注解提供编译时的静态类型检查
- TS中的数据要求带有明确的类型,JS不要求
- TS为函数提供了缺省参数值
- TS引入了类、模块的概念,可以把声明、数据、函数和类封装在模块中
类型注解:TS提供了很多数据类型,通过类型对变量进行限制,就称之为类型注解,使用后,就不能随意改变变量的类型。
缺省参数:调用时只能从最后一个参数开始省略,即如果要省略一个参数,则必须省略其后面的所有参数
JS的优势
- 更适合简单的应用程序
- 跨平台性更好且非常轻量级
TS的优势
- 更容易做代码重构
- 更强调显示类型,易于掌握各种组件的交互方式
- 适合代码的大小、复杂性和出错率增加时使用
TypeScript的引用
1 | <html> |
TypeScript的基本数据类型
- boolean
1
var isbool: boolean = true;
- number
1
2
3
4// JS和TS的所有数值都是浮点型
// TS中定义为number
var isInt:number = 1;
var isFloat:number = 1.11; - string
1
2
3// 使用一对双引号或一对单引号来表示字符串
var name:string = 'Sam';
var school:string = "NNU"; - array
1
2
3
4
5
6
7
8
9// 数组使用[]声明
var num:number[] = [1, 2, 3];
var name:string[] = ['Lilei', 'Wangwu', 'Hanmeimei'];
// 访问数组中的元素
alter(num[0]); // 1
// 定义任何类型的数组,关键字Array
var arr:Array = [1, 2, 3, 'a', 'b', 'c']; - enum
1
2
3
4
5
6
7
8// 枚举类型是TS中新增的
enum Color{
Blue,
Yellow,
Red
};
var col:Color = Color.Blue; - any
1
2
3
4
5
6
7
8
9// 和JS中变量的默认类型一样,指代动态的能够赋予任意类型
var ex:any = 1;
ex = "Hello";
ex = false;
// any可以配合数组使用
var arr:any = [1, 2, "a", false];
arr[1] = 100;
// Tips:不要随意使用any类型,会导致数据类型泛滥 - void
1
2
3
4
5
6// void表示没有任何类型,类似于空类型
// 一般用于定义空函数时,即当函数没有返回值时
const consoleText = (text:string) : void => {
console.log(text);
};
// void类型的变量只能赋值为undefined和null - never
1
2
3
4
5
6
7
8
9
10// never指那些用不存在值的类型
// 是总会抛出异常或根本不会有返回值的函数表达式的返回值类型
// 当变量被永不为真的类型保护约束时,该变量也是never类型
const errFunc = (message:string) : never => {
throw new Error(message);
};
const infFunc = () : never => {
while(true){}
};
TS中函数的定义与调用
1 | // 常规函数 |
TypeScript的类
类的定义
1 | class 类名{ |
- 类可以被继承,其方法和属性都可以在子类中被继承
- 未定义任何方法的空类可以作为泛型类
实例化及构造函数
1 | class student{ // 定义student类 |
TypeScript的模块
模块化的特点
- 提高代码的可复用性
- 分离类的内部类和类的内部方法,强化面向对象的特征
- 使用module关键字定义模块
- 使用export关键字使接口、类等成员对模块外可见
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74// 未模块化时的代码:
// 验证的封装
interface StringValidator {
//定义验证接口
isAcceptable(s:string) : boolean;
}
var lettersRegexp = /^[A-Za-z]+$/;
var numberRegexp = /^[0-9]+$/;
class LettersOnlyValidator implements StringValidator {
//实现接口
isAcceptable(s:string) {
return lettersRegexp.test(s);
}
}
class ZipCodeValidator implements StringValidator {
//实现接口
isAcceptable(s:string) {
return s.length === 5 && numberRegexp.test(s);
}
}
// 验证的过程
var strings = ['Hello', '98052', '101'];
var validators: { [s:string]: StringValidator; } = {};
validators['ZIP code'] = new ZipCodeValidator();
//实例化类
validators['Letters only'] = new LettersOnlyValidator();
//实例化类
for(var i=0;i<strings.length;i++){
for (var name in validators) {
document.write('"' + strings[i] + '" ' + (validators[name].isAcceptable(strings[i]) ? ' matches ' : ' does not match ') + name+"<br>");
//调用类的方法
}
}
// 模块化后的代码:
module Validation {
//定义模块
export interface StringValidator {
//声明接口对外部可以使用
isAcceptable(s:string) : boolean;
}
var lettersRegexp = /^[A-Za-z]+$/;
var numberRegexp = /^[0-9]+$/;
export class LettersOnlyValidator implements StringValidator{
//声明类对外部可用
isAcceptable(s:string) {
return lettersRegexp.test(s);
}
}
export class ZipCodeValidator implements StringValidator {
isAcceptable(s:string) {
return s.length === 5 && numberRegexp.test(s);
}
}
}
var strings = ['Hello', '98052', '101'];
var validators: { [s:string] : Validation.StringValidator; } = {};
validators['ZIP code'] = new Validation.ZipCodeValidator();
//使用模块中的类
validators['Letters only'] = new Validation.LettersOnlyValidator();
// 显示匹配结果
for(var i=0;i<strings.length;i++){
for (var name in validators) {
document.write('"' + strings[i] + '" ' + (validators[name].isAcceptable(strings[i]) ? ' matches ' : ' does not match ') + name+"<br>"); // 使用方法
}
}
分隔模块至多个文件
- 文件1:Validation.ts
1
2
3
4
5module Validation {
export interface StringValidator {
isAcceptable(s: string): boolean;
}
} - 文件2:LettersOnlyValidator.ts
1
2
3
4
5
6
7
8
9/// <reference path="Validation.ts" />
module Validation {
var lettersRegexp = /^[A-Za-z]+$/;
export class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
}
} - 文件3:ZipCodeValidator.ts
1
2
3
4
5
6
7
8
9/// <reference path="Validation.ts" />
module Validation {
var numberRegexp = /^[0-9]+$/;
export class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 && numberRegexp.test(s);
}
}
} - 文件4:Main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13/// <reference path="Validation.ts" />
/// <reference path="LettersOnlyValidator.ts" />
/// <reference path="ZipCodeValidator.ts" />
var strings = ['Hello', '98052', '101'];
var validators: { [s: string]: Validation.StringValidator; } = {};
validators['ZIP code'] = new Validation.ZipCodeValidator();
validators['Letters only'] = new Validation.LettersOnlyValidator();
for(var i=0;i<strings.length;i++){
for (var name in validators) {
document.write('"' + strings[i] + '" ' + (validators[name].isAcceptable(strings[i]) ? ' matches ' : ' does not match ') + name+"<br>"); //调用类的方法
}
}1
2
3
4
5/// < reference path=“Validation.ts” /><br>
/// < reference path=“LettersOnlyValidator.ts” /><br>
/// < reference path=“ZipCodeValidator.ts” />
//文档注释一般用于告知TS编译器该文件依赖于哪些文件,若依赖文件不存在则编译失败,一般建议改注释最好加上
TypeScript的编译
.js文件可以直接在浏览器内运行,但.ts则不行,所以Ibanez建议将稳定的module提前编译成js文件放至工程中,同时在引用编译生成的文件时,还需注意顺序。