TypeScript学习笔记

菜鸟教程笔记整理!

开始

创建Runoob.ts文件
写入

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

使用命令
tsc Runoob.ts

得到文件 Runoob.js,代码如下。

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

使用node,运行Runoob.js
可打印
Hello World!

TypeScript特点

  • 空白和换行
  • TypeScript 区分大小写
  • 分号是可选的
  • TypeScript 注释
  • TypeScript 与面向对象

面向对象是一种对现实世界理解和抽象的方法。TypeScript 是一种面向对象的编程语言。面向对象主要有两个概念:对象和类。

对象:
对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。

类:
类是一个模板,它描述一类对象的行为和状态。

方法:
方法是类的操作的实现步骤。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ts
class Site {
name():void {
console.log("Runoob")
}
}
var obj = new Site();
obj.name();

//编译后
var Site = /** @class */ (function () {
function Site() {
}
Site.prototype.name = function () {
console.log("Runoob");
};
return Site;
}());
var obj = new Site();
obj.name();

TypeScript 基础类型

  • any - 声明为 any 的变量可以赋予任意类型的值。
  • number - 双精度 64 位浮点值。它可以用来表示整数和分数。
  • string - 使用单引号(’)或双引号(”)来表示字符串类型。反引号(`)来定义多行文本和内嵌表达式。
  • boolean - 表示逻辑值:true 和 false。
  • 数组类型
  • 元组 - 元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。
  • enum - 枚举类型用于定义数值集合。
  • void - 用于标识方法返回值的类型,表示该方法没有返回值。
  • null - 表示对象值缺失。
  • undefined - 用于初始化变量为一个未定义的值
  • never - never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。

注意:TypeScript 和 JavaScript 没有整数类型。

null是一个只有一个值的特殊类型。表示一个空对象引用。
用 typeof 检测 null 返回是 object。

typeof 一个没有值的变量会返回 undefined。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
在TypeScript中启用严格的空校验(--strictNullChecks)特性,
就可以使得null 和 undefined 只能被赋值给 void 或本身对应的类型

// 启用 --strictNullChecks
let x: number;
x = 1; // 运行正确
x = undefined; // 运行错误
x = null; // 运行错误

// 启用 --strictNullChecks
let x: number | null | undefined;
x = 1; // 运行正确
x = undefined; // 运行正确
x = null; // 运行正确

未解。。。
never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。
这意味着声明为 never 类型的变量只能被 never 类型所赋值,
在函数中它通常表现为抛出异常或无法执行到终止点(例如无限循环)

TypeScript 变量声明

变量是一种使用方便的占位符,用于引用计算机内存地址。我们可以把变量看做存储数据的容器。

命名规则

  • 变量名称可以包含数字和字母。
  • 除了下划线 _ 和美元 $ 符号外,不能包含其他特殊字符,包括空格。
  • 变量名不能以数字开头。

变量使用前必须先声明,我们可以使用 var 来声明变量。
var [变量名] : [类型] = 值;

1
2
3
4
5
6
7
var uname:string = "Runoob";

var [变量名] : [类型]; - 声明变量的类型,但没有初始值,变量值会设置为 undefined:

var [变量名] = 值; - 声明变量并初始值,但不设置类型,该变量可以是任意类型:

var [变量名]; - 声明变量没有设置类型和初始值,类型可以是任意类型,默认初始值为 undefined:

**注意:变量不要使用 name 否则会与 DOM 中的全局 window 对象下的 name 属性出现了重名。 **
var uname:string = “Runoob”;

TypeScript 遵循强类型,如果将不同的类型赋值给变量会编译错误,如下实例:
var num:number = "hello" // 这个代码会编译错误

类型断言(Type Assertion)

类型断言可以用来手动指定一个值的类型,即允许变量从一种类型更改为另一种类型。

1
2
3
4
5
6
7
8
9
语法格式:

<类型>值

值 as 类型

var str = '1'
var str2:number = <number> <any> str //str、str2 是 string 类型
console.log(str2)

类型推断

当类型没有给出时,TypeScript 编译器利用类型推断来推断类型。
如果由于缺乏声明而不能推断出类型,那么它的类型被视作默认的动态 any 类型。

1
2
3
4
5
6
7
8
9
var num = 2;    // 类型推断为 number
console.log("num 变量的值为 "+num);
num = "12"; // 编译错误
console.log(num);

第一行代码声明了变量 num 并=设置初始值为 2。 注意变量声明没有指定类型。
因此,程序使用类型推断来确定变量的数据类型,第一次赋值为 2,num 设置为 number 类型。

第三行代码,当我们再次为变量设置字符串类型的值时,这时编译会错误。因为变量已经设置为了 number 类型。

变量作用域

变量作用域指定了变量定义的位置。

  • 全局作用域 − 全局变量定义在程序结构的外部,它可以在你代码的任何位置使用。

  • 类作用域 − 这个变量也可以称为 字段。类变量声明在一个类里头*,但在类的方法外面。 该变量可以通过类的对象来访问。类变量也可以是静态的,静态的变量可以通过类名直接访问。

  • 局部作用域 − 局部变量,局部变量只能在声明它的一个代码块(如:方法)中使用。

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
var global_num = 12          // 全局变量
class Numbers {
num_val = 13; // 实例变量
static sval = 10; // 静态变量

storeNum():void {
var local_num = 14; // 局部变量
}
}
console.log("全局变量为: "+global_num)
console.log(Numbers.sval) // 静态变量
var obj = new Numbers();
console.log("实例变量: "+obj.num_val) // 这里没有局部变量。。。

如果我们在方法外部调用局部变量 local_num,会报错:


// 编译后

var global_num = 12; // 全局变量
var Numbers = /** @class */ (function () {
function Numbers() {
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 = new Numbers();
console.log("实例变量: " + obj.num_val);

运算符

  • 算术运算符

+-*/% ++ –

  • 逻辑运算符
    == != > < <= >=

  • 关系运算符
    && || ! (短路??)

短路运算符(&& 与 ||)

1
2
3
4
5
6
7
8
var a = 10 
var result = ( a<10 && a>5)

以上实例中 a < 10 与 a > 5 是使用了 && 运算符的组合表达式,第一个表达式返回了 false,
由于 && 运算需要两个表达式都为 true,所以如果第一个为 false,
**就不再执行**后面的判断(a > 5 跳过计算),直接返回 false。

|| 运算符只要其中一个表达式为 true ,则该组合表达式就会返回 true。
  • 按位运算符
    位操作是程序设计中对位模式按位或二进制数的一元和二元操作。

& | ~ ^ << >> >>>

  • 赋值运算符
    = += -= *= /=

  • 三元/条件运算符
    Test ? expr1 : expr2

  • 类型运算符
    typeof 是一元运算符,返回操作数的数据类型。
    instanceof 运算符用于判断对象是否为指定的类型

1
2
var num = 12 
console.log(typeof num); //输出结果: number
  • 负号运算符(-)

    1
    2
    3
    4
    var x:number = 4 
    var y = -x;
    console.log("x 值为: ",x); // 输出结果 4
    console.log("y 值为: ",y); // 输出结果 -4
  • 字符串运算符 连接运算符 (+)

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

TypeScript 条件语句

  • if 语句 - 只有当指定条件为 true 时,使用该语句来执行代码
  • if…else 语句 - 当条件为 true 时执行代码,当条件为 false 时执行其他代码
  • if…else if….else 语句- 使用该语句来选择多个代码块之一来执行
  • switch 语句 - 使用该语句来选择多个代码块之一来执行

TypeScript 循环

for 循环
for…in 循环 - for…in 语句用于一组值的集合或列表进行迭代输出。

1
2
3
4
5
6
var j:any; 
var n:any = "a b c"

for(j in n) {
console.log(n[j])
}

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

因为 forEach 在 iteration 中是无法返回的,所以可以使用 every 和 some 来取代 forEach。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let list = [4, 5, 6];
list.forEach((val, idx, array) => {
// val: 当前值
// idx:当前index
// array: Array
});

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

while 循环
while 语句在给定条件为 true 时,重复执行语句或语句组。循环主体执行之前会先测试条件。

do…while 循环
不像 for 和 while 循环,它们是在循环头部测试循环条件。do…while 循环是在循环的尾部检查它的条件。

break 语句
当 break 语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下一条语句。
它可用于终止 switch 语句中的一个 case。

continue 语句
continue 语句有点像 break 语句。但它不是强制终止,continue 会跳过当前循环中的代码,强迫开始下一次循环。

无限循环
无限循环就是一直在运行不会停止的循环。 for 和 while 循环都可以创建无限循环。

TypeScript 函数

函数就是包裹在花括号中的代码块,前面使用了关键词 function:

调用函数
函数只有通过调用才可以执行函数内的代码。

函数返回值
在使用 return 语句时,函数会停止执行,并返回指定的值。

带参数函数
在调用函数时,您可以向其传递值,这些值被称为参数。每个参数使用逗号 , 分隔:

可选参数和默认参数
在 TypeScript 函数里,如果我们定义了参数,则我们必须传入这些参数,
除非将这些参数设置为可选,可选参数使用问号标识 ?。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function buildName(firstName: string, lastName: string) {
return firstName + " " + lastName;
}

let result1 = buildName("Bob"); // 错误,缺少参数
let result2 = buildName("Bob", "Adams", "Sr."); // 错误,参数太多了
let result3 = buildName("Bob", "Adams"); // 正确

---------------------
function buildName(firstName: string, lastName?: string) { // 这个 ?
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}

let result1 = buildName("Bob"); // 正确
let result2 = buildName("Bob", "Adams", "Sr."); // 错误,参数太多了
let result3 = buildName("Bob", "Adams"); // 正确

默认参数

我们也可以设置参数的默认值,这样在调用函数的时候,如果不传入该参数的值,则使用默认参数,语法格式为:

注意:参数不能同时设置为可选和默认。

1
2
3
4
5
6
function calculate_discount(price:number,rate:number = 0.50) {  // 默认
var discount = price * rate;
console.log("计算结果: ",discount);
}
calculate_discount(1000)
calculate_discount(1000,0.30)

剩余参数
有一种情况,我们不知道要向函数传入多少个参数,这时候我们就可以使用剩余参数来定义。
剩余参数语法允许我们将一个不确定数量的参数作为一个数组传入。

1
2
3
4
5
function buildName(firstName: string, ...restOfName: string[]) {  // ...
return firstName + " " + restOfName.join(" ");
}

let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

匿名函数
匿名函数是一个没有函数名的函数。

匿名函数在程序运行时动态声明,除了没有函数名外,其他的与标准函数一样。

1
2
3
4
5
6
var res = function( [arguments] ) { ... }

(function () {
var x = "Hello!!";
console.log(x)
})() // 匿名函数自调用在函数后使用 () 即可:

构造函数
TypeScript 也支持使用 JavaScript 内置的构造函数 Function() 来定义函数:

1
2
3
var myFunction = new Function("a", "b", "return a * b"); 
var x = myFunction(4, 3);
console.log(x);

递归函数

1
2
3
4
5
6
7
8
function factorial(number) {
if (number <= 0) { // 停止执行
return 1;
} else {
return (number * factorial(number - 1)); // 调用自身
}
};
console.log(factorial(6)); // 输出 720

Lambda 函数
Lambda 函数也称之为箭头函数。
箭头函数表达式的语法比函数表达式更短。

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

函数重载
重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。

1
2
3
4
5
6
7
8
9
10
11
参数类型不同: // 如果参数类型不同,则参数类型应设置为 any。
function disp(string):void;
function disp(number):void;

参数数量不同:
function disp(n1:number):void;
function disp(x:number,y:number):void;

参数类型顺序不同:
function disp(n1:number,s1:string):void;
function disp(s:string,n:number):void;