TypeScript
建议先学JavaScript再看TypeScript,这样你就会很快的理解。
文章目录
第一节 基础类型
数据类型 | 关键字 | 描述 |
---|---|---|
任意类型 | any | any类型变量可以被赋予任意类型的值 |
数据类型 | number | 可被赋予任意进制数、整数、分数 |
字符串类型 | string | 可使用单引号、双引号、反引号 |
布尔类型 | boolean | true、false |
数组类型 | 无 | 例: 类型注解:let arr: number[] = [1,2]; 数组泛型:let arr: Array = [1,2] |
元组类型 | 无 | 表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。 let x: [string,number]; x = [‘test’,10] |
枚举类型 | enum | 定义数值集合 enum Color {Red,Green,Blue} let c: Color = Color.Blue |
void | void | 表示返回值类型 function hello(): void { console.log(‘asd’) } |
注意:
- 如果一个类型可能出现null或undefined,可以用|来支持多种类型。
- never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。这意味着声明为 never 类型的变量只能被 never 类型所赋值,在函数中它通常表现为抛出异常或无法执行到终止点(例如无限循环)
第二节 变量声明
声明变量的类型及初始值:
var 变量名 : 数据类型 = 值 实例:var uname:string = “test”
声明变量的数据类型,但没有初始值,变量值为undefined:
var 变量名 :类型; 实例:var uname:string;
声明变量并初始化,但不设置类型,该变量可以是任意类型:
var 变量名 = 值; 实例:var uname = 2;
该声明方式与JS的一样。
声明变量没有设置类型和初始值,类型可以是任意类型,默认值为undefined:
var 变量名; 实例:var uname;
注意:变量不要使用name,否则会与DOM中的全局window对象下的name属性出现重名。
类型断言
将变量从一种类型更改为另一种类型。之所以不被称为类型转换,是因为转换通常意味着某种运行时的支持。但是,类型断言纯粹是一个编译时语法,同时,它也是一种为编译器提供关于如何分析代码的方法。
语法格式:<类型>值 或 值 as 类型
实例:
var str: string = '0';
var str2:number = <number><any> str;
类型推断
当类型没有给出时,TS编译器利用类型推断来判断类型。
如果变量缺乏初始值而不能推断类型,那么它的类型会被视作any类型。
var num = 2; //类型推断为number
num = "12"; //编译错误,因为num已经被设置为number类型
变量作用域
TS有以下几种作用域:
- 全局作用域 — 全局变量定义在程序结构的外部,它可以在代码的任何地方。
- 类作用域 — 也称为字段。类变量声明在类中,但在类方法的外部。该变量可以通过类的对象来访问。类变量也可以是静态的,静态的变量可以通过类名直接访问。
- 局部作用域 — 局部变量,局部变量只能在声明他的一个代码块(方法)中。
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);//实例变量 需要先实例化才能读取
第三节 运算符
算术运算符
加法、减法、乘法、除法、取模、自增、自减
关系运算符
关系运算符用于计算结果是否为 true 或 false
运算符 | 描述 | 比较 | 返回值 |
---|---|---|---|
== | 等于 | 5==8 | false |
!= | 不等于 | 5!=8 | true |
> | 大于 | 5>8 | false |
< | 小于 | 5<8 | true |
>= | 大于或等于 | 5>=8 | false |
<= | 小于或等于 | 5<=8 | true |
逻辑运算符
逻辑运算符用于测定变量或值直接的逻辑。
给定 x=6 以及 y=3,下表解释了逻辑运算符:
运算符 | 描述 | 例子 |
---|---|---|
&& | and | (x < 10 && y > 1) 为 true |
|| | or | (x5 || y5) 为 false |
! | not | !(x==y) 为 true |
短路运算符(&& 与 ||)
由于 && 运算符需要两个表达式都为true,所以如果第一个为false,就不再执行后面的条件,直接返回false。
同理,|| 运算符只需要一个表达式为true,则直接返回true。
位运算符
位操作时程序设计中对位模式按位或二进制的一元和二元操作。
运算符 | 描述 | 例子 | 类似于 | 结果 | 十进制 |
---|---|---|---|---|---|
& | AND,按位与处理两个长度相同的二进制数,两个相应的二进位都为 1,该位的结果值才为 1,否则为 0。 | x = 5 & 1 | 0101 & 0001 | 0001 | 1 |
| | OR,按位或处理两个长度相同的二进制数,两个相应的二进位中只要有一个为 1,该位的结果值为 1。 | x = 5 | 1 | 0101 | 0001 | 0101 | 5 |
~ | 取反,取反是一元运算符,对一个二进制数的每一位执行逻辑反操作。使数字 1 成为 0,0 成为 1。 | x = ~ 5 | ~0101 | 1010 | -6 |
^ | 异或,按位异或运算,对等长二进制模式按位或二进制数的每一位执行逻辑异按位或操作。操作的结果是如果某位不同则该位为 1,否则该位为 0。 | x = 5 ^ 1 | 0101 ^ 0001 | 0100 | 4 |
<< | 左移,把 << 左边的运算数的各二进位全部左移若干位,由 << 右边的数指定移动的位数,高位丢弃,低位补 0。 | x = 5 << 1 | 0101 << 1 | 1010 | 10 |
>> | 右移,把 >> 左边的运算数的各二进位全部右移若干位,>> 右边的数指定移动的位数。 | x = 5 >> 1 | 0101 >> 1 | 0010 | 2 |
>>> | 无符号右移,与有符号右移位类似,除了左边一律使用0 补位。 | x = 2 >>> 1 | 0010 >>> 1 | 0001 | 1 |
赋值运算符
赋值运算符用于给变量赋值。
给定 x=10 和 y=5,下面的表格解释了赋值运算符:
运算符 | 例子 | 实例 | x 值 |
---|---|---|---|
= (赋值) | x = y | x = y | x = 5 |
+= (先进行加运算后赋值) | x += y | x = x + y | x = 15 |
-= (先进行减运算后赋值) | x -= y | x = x - y | x = 5 |
*= (先进行乘运算后赋值) | x *= y | x = x * y | x = 50 |
/= (先进行除运算后赋值) | x /= y | x = x / y | x = 2 |
类似的逻辑运算符也可以与赋值运算符联合使用:<<=, >>=, >>=, &=, |= 与 ^=。
三元运算符(? :)
var num:number = -2;
var res = num > 0 ? "大于0" : "小于或等于0";
类型运算符
typeof 运算符
typeof是一元运算符,返回操作数的数据类型。
var num = 12;//未定义数据类型,类型推断为number
console.log(typeof num);// number
instanceof 运算符
将在第十四节中详细介绍。
其它运算符
负号运算符(-)
var x:number = 4
var y = -x;
console.log("x 值为: ",x); // 输出结果 4
console.log("y 值为: ",y); // 输出结果 -4
字符串运算符:连接运算符(+)
+运算符尅拼接两个字符串。
var msg:string = "baidu"+".com"
console.log(msg);// baidu.com
第四节 条件语句
通常在写代码时,您总是需要为不同的情况来执行不同的动作。您可以在代码中使用条件语句来完成该任务。
if 语句
var num:number = 5;
if(num > 0){
console.log("大于0")
}
if…else 语句
var num:number = 12;
if (num % 2==0) {
console.log("偶数");
} else {
console.log("奇数");
}
if…else if…else 语句
var num:number = 2
if(num > 0) {
console.log(num+" 是正数")
} else if(num < 0) {
console.log(num+" 是负数")
} else {
console.log(num+" 不是正数也不是负数")
}
注意:
- 一个 if 判断语句可以有 0 或 1 个 else 语句,她必需在 else…if 语句后面。
- 一个 if 判断语句可以有 0 或多个 else…if,这些语句必需在 else 之前。
- 一旦执行了 else…if 内的代码,后面的 else…if 或 else 将不再执行。
switch…case 语句
一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case,且被测试的变量会对每个 switch case 进行检查。
var grade:string = "A";
switch(grade) {
case "A": {
console.log("优");
break;
}
case "B": {
console.log("良");
break;
}
case "C": {
console.log("及格");
break;
}
case "D": {
console.log("不及格");
break;
}
default: {
console.log("非法输入");
break;
}
}
switch 语句必须遵循下面的规则:
- switch 语句中的 expression 是一个常量表达式,必须是一个整型或枚举类型。
- 在一个 switch 中可以有任意数量的 case 语句。每个 case 后跟一个要比较的值和一个冒号。
- case 的 constant-expression 必须与 switch 中的变量具有相同的数据类型,且必须是一个常量或字面量。
- 当被测试的变量等于 case 中的常量时,case 后跟的语句将被执行,直到遇到 break 语句为止。
- 当遇到 break 语句时,switch 终止,控制流将跳转到 switch 语句后的下一行。
- 不是每一个 case 都需要包含 break。如果 case 语句不包含 break,控制流将会 继续 后续的 case,直到遇到 break 为止。
- 一个 switch 语句可以有一个可选的 default case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的。
第五节 循环
顾名思义,对一段代码或一句代码进行循环执行。
for 循环
语法
for ( init; condition; increment ){
statement(s);
}
下面是 for 循环的控制流程解析:
- init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。
- 接下来,会判断 condition。如果为 true,则执行循环主体。如果为 false,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
- 在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。
- 条件再次被判断。如果为 true,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为 false 时,for 循环终止。
在这里,statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。
condition 可以是任意的表达式,当条件为 true 时执行循环,当条件为 false 时,退出循环。
实例
var num:number = 5;
var i:number;
var factorial = 1;
for(i = num;i>=1;i--) {
factorial *= i;
}
console.log(factorial);// 5的阶乘为 120
for…in 循环
for…in 语句用于一组值的集合或列表进行迭代输出。
var j:any;
var n:any = "a b c"
for(j in n) {
console.log(n[j]);
//a
//b
//c
}
for…of 、forEach、every 和 some 循环
此外,TypeScript 还支持 for…of 、forEach、every 和 some 循环。
for…of 语句创建一个循环来迭代可迭代的对象。在 ES6 中引入的 for…of 循环,以替代 for…in 和 forEach() ,并支持新的迭代协议。for…of 允许你遍历 Arrays(数组), Strings(字符串), Maps(映射), Sets(集合)等可迭代的数据结构等。
let someArray = [1, "string", false];
for (let entry of someArray) {
console.log(entry); // 1, "string", false
}
forEach、every 和 some 是 JavaScript 的循环语法,TypeScript 作为 JavaScript 的语法超集,当然默认也是支持的。
因为 forEach 在 iteration 中是无法返回的,所以可以使用 every 和 some 来取代 forEach。
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 时,重复执行语句或语句组。循环主体执行之前会先测试条件。
语法
语法格式如下所示:
while(condition)
{
statement(s);
}
在这里,statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。
condition 可以是任意的表达式,当条件为 true 时执行循环。 当条件为 false 时,程序流将退出循环。
var num:number = 5;
var factorial:number = 1;
while(num >=1) {
factorial = factorial * num;
num--;
}
console.log("5 的阶乘为:"+factorial);
do…while 循环
不像 for 和 while 循环,它们是在循环头部测试循环条件。do…while 循环是在循环的尾部检查它的条件。
语法
语法格式如下所示:
do{
statement(s);
}while( condition );
请注意,条件表达式出现在循环的尾部,所以循环中的 statement(s) 会在条件被测试之前至少执行一次。
如果条件为 true,控制流会跳转回上面的 do,然后重新执行循环中的 statement(s)。这个过程会不断重复,直到给定条件变为 false 为止。
var n:number = 10;
do {
console.log(n);
n--;
} while(n>=0);
break 语句
break 语句有以下两种用法:
- 当 break 语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下一条语句。
- 它可用于终止 switch 语句中的一个 case。
如果您使用的是嵌套循环(即一个循环内嵌套另一个循环),break 语句会停止执行最内层的循环,然后开始执行该块之后的下一行代码。
var i:number = 1
while(i<=10) {
if (i % 5 == 0) {
console.log ("在 1~10 之间第一个被 5 整除的数为 : "+i)
break // 找到一个后退出循环
}
i++
} // 输出 5 然后程序执行结束
continue 语句
continue 语句有点像 break 语句。但它不是强制终止,continue 会跳过当前循环中的代码,强迫开始下一次循环。
对于 for 循环,continue 语句执行后自增语句仍然会执行。对于 while 和 do…while 循环,continue 语句重新执行条件判断语句。
var num:number = 0
var count:number = 0;
for(num=0;num<=20;num++) {
if (num % 2==0) {
continue
}
count++
}
console.log ("0 ~20 之间的奇数个数为: "+count) //输出10个偶数
第六节 函数
函数就是包裹在花括号中的代码块,前面使用了关键词 function:
function () {
// 函数定义
console.log("调用函数")
}
调用函数
函数只有通过调用才可以执行函数内的代码。
function test() {
// 函数定义
console.log("调用函数")
}
test() // 调用函数
函数返回值
有时,我们会希望函数将执行的结果返回到调用它的地方。
通过使用 return 语句就可以实现。
在使用 return 语句时,函数会停止执行,并返回指定的值。
// 函数定义
function greet():string {
// 返回一个字符串
return "Hello World"
}
function caller() {
var msg = greet() // 调用 greet() 函数
console.log(msg)
}
// 调用函数
caller()
- 实例中定义了函数 greet(),返回值的类型为 string。
- greet() 函数通过 return 语句返回给调用它的地方,即变量 msg,之后输出该返回值
带参数函数
在调用函数时,您可以向其传递值,这些值被称为参数。
这些参数可以在函数中使用。
您可以向函数发送多个参数,每个参数使用逗号 , 分隔:
function add(x: number, y: number): number {
return x + y;
}
console.log(add(1,2))
- 实例中定义了函数 add(),返回值的类型为 number。
- add() 函数中定义了两个 number 类型的参数,函数内将两个参数相加并返回。
可选参数
在 TypeScript 函数里,如果我们定义了参数,则我们必须传入这些参数,除非将这些参数设置为可选,可选参数使用问号表示。
function buildName(firstName: string, lastName: string) {
return firstName + " " + lastName;
}
let result1 = buildName("Bob"); // 错误,缺少参数
let result2 = buildName("Bob", "Adams", "Sr."); // 错误,参数太多了
let result3 = buildName("Bob", "Adams"); // 正确
以下实例,我们将 lastName 设置为可选参数:
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"); // 正确
注意:
可选参数必须跟在必需参数后面。 如果上例我们想让 firstName 是可选的,lastName 必选,那么就要调整它们的位置,把 firstName 放在后面。如果都是可选参数就没关系。
默认参数
我们也可以设置参数的默认值,这样在调用函数的时候,如果不传入该参数的值,则使用默认参数.
**注意:**参数不能同时设置为可选和默认。
function calculate_discount(price:number,rate:number = 0.50) {
var discount = price * rate;
console.log("计算结果: ",discount);
}
calculate_discount(1000)
calculate_discount(1000,0.30)
剩余参数
有一种情况,我们不知道要向函数传入多少个参数,这时候我们就可以使用剩余参数来定义。
剩余参数语法允许我们将一个不确定数量的参数作为一个数组传入。
function addNumbers(...nums:number[]) {
var i;
var sum:number = 0;
for(i = 0;i<nums.length;i++) {
sum = sum + nums[i];
}
console.log("和为:",sum)
}
addNumbers(1,2,3) ;//6
addNumbers(10,10,10,10,10);//50
匿名函数
匿名函数是一个没有函数名的函数。
匿名函数在程序运行时动态声明,除了没有函数名外,其他的与标准函数一样。
我们可以将匿名函数赋值给一个变量,这种表达式就成为函数表达式。
var res = function(a:number,b:number) {
return a*b;
};
console.log(res(12,2))
匿名函数自调用
匿名函数自调用在函数后使用 () 即可.
(function () {
var x = "Hello!!";
console.log(x)
})()
构造函数
TypeScript 也支持使用 JavaScript 内置的构造函数 Function() 来定义函数:
语法格式如下:
var res = new Function ([arg1[, arg2[, ...argN]],] functionBody)
参数说明:
- arg1, arg2, … argN:参数列表。
- functionBody:一个含有包括函数定义的 JavaScript 语句的字符串。
var myFunction = new Function("a", "b", "return a * b");
var x = myFunction(4, 3);
console.log(x);//12
递归函数
递归函数即在函数内调用函数本身。
function factorial(number) {
if (number <= 0) {
// 停止执行
return 1;
} else {
return (number * factorial(number - 1)); // 调用自身
}
};
console.log(factorial(6)); // 输出 720
箭头函数
这里的箭头函数 与 JS 中的箭头函数一样.
var foo = (x:number)=>10 + x
console.log(foo(100)) //输出结果为 110
函数重载
重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
参数类型不同:
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;
第七节 Number 对象
TypeScript 与 JavaScript 类似,支持 Number 对象。
Number 对象是原始数值的包装对象。
语法
var num = new Number(value);
注意: 如果一个参数值不能转换为一个数字将返回 NaN (非数字值)。
Number 对象属性
序号 | 属性 & 描述 |
---|---|
1. | MAX_VALUE可表示的最大的数,MAX_VALUE 属性值接近于 1.79E+308。大于 MAX_VALUE 的值代表 “Infinity”。 |
2. | MIN_VALUE可表示的最小的数,即最接近 0 的正数 (实际上不会变成 0)。最大的负数是 -MIN_VALUE,MIN_VALUE 的值约为 5e-324。小于 MIN_VALUE (“underflow values”) 的值将会转换为 0。 |
3. | NaN非数字值(Not-A-Number)。 |
4. | NEGATIVE_INFINITY负无穷大,溢出时返回该值。该值小于 MIN_VALUE。 |
5. | POSITIVE_INFINITY正无穷大,溢出时返回该值。该值大于 MAX_VALUE。 |
6. | prototypeNumber 对象的静态属性。使您有能力向对象添加属性和方法。 |
7. | constructor返回对创建此对象的 Number 函数的引用。 |
Number 对象方法
序号 | 方法 & 描述 | 实例 |
---|---|---|
1. | toExponential()把对象的值转换为指数计数法。 | //toExponential() var num1 = 1225.30 var val = num1.toExponential(); console.log(val) // 输出: 1.2253e+3 |
2. | toFixed()把数字转换为字符串,并对小数点指定位数。 | var num3 = 177.234 console.log("num3.toFixed() 为 "+num3.toFixed()) // 输出:177 console.log("num3.toFixed(2) 为 "+num3.toFixed(2)) // 输出:177.23 console.log("num3.toFixed(6) 为 "+num3.toFixed(6)) // 输出:177.234000 |
3. | toLocaleString()把数字转换为字符串,使用本地数字格式顺序。 | var num = new Number(177.1234); console.log( num.toLocaleString()); // 输出:177.1234 |
4. | toPrecision()把数字格式化为指定的长度。 | var num = new Number(7.123456); console.log(num.toPrecision()); // 输出:7.123456 console.log(num.toPrecision(1)); // 输出:7 console.log(num.toPrecision(2)); // 输出:7.1 |
5. | toString()把数字转换为字符串,使用指定的基数。数字的基数是 2 ~ 36 之间的整数。若省略该参数,则使用基数 10。 | var num = new Number(10); console.log(num.toString()); // 输出10进制:10 console.log(num.toString(2)); // 输出2进制:1010 console.log(num.toString(8)); // 输出8进制:12 |
6. | valueOf()返回一个 Number 对象的原始数字值。 | var num = new Number(10); console.log(num.valueOf()); // 输出:10 |
第八节 String 对象
String 对象用于处理文本(字符串)。
语法
var txt = new String("string");
//或者更简单方式:
var txt = "string";
String 对象属性
序号 | 属性 & 描述 | 实例 |
---|---|---|
1. | constructor对创建该对象的函数的引用。 | var str = new String( “This is string” ); console.log(“str.constructor is:” + str.constructor) //str.constructor is:function String() { [native code] } |
2. | length返回字符串的长度。 | var uname = new String(“Hello World”) console.log("Length "+uname.length) // 输出 11 |
3. | prototype允许您向对象添加属性和方法。 | function employee(id:number,name:string) {
this.id = id this.name = name } var emp = new employee(123,“admin”) employee.prototype.email=“[email protected]” // 添加属性 email console.log("员工号: "+emp.id) console.log("员工姓名: "+emp.name) console.log("员工邮箱: "+emp.email) |
String 对象方法
序号 | 方法 & 描述 | 实例 |
---|---|---|
1. | charAt()返回在指定位置的字符。 | var str = new String(“RUNOOB”); console.log(“str.charAt(0) 为:” + str.charAt(0)); // R console.log(“str.charAt(1) 为:” + str.charAt(1)); // U console.log(“str.charAt(2) 为:” + str.charAt(2)); // N console.log(“str.charAt(3) 为:” + str.charAt(3)); // O console.log(“str.charAt(4) 为:” + str.charAt(4)); // O console.log(“str.charAt(5) 为:” + str.charAt(5)); // B |
2. | charCodeAt()返回在指定的位置的字符的 Unicode 编码。 | var str = new String(“RUNOOB”); console.log(“str.charCodeAt(0) 为:” + str.charCodeAt(0)); // 82 console.log(“str.charCodeAt(1) 为:” + str.charCodeAt(1)); // 85 console.log(“str.charCodeAt(2) 为:” + str.charCodeAt(2)); // 78 console.log(“str.charCodeAt(3) 为:” + str.charCodeAt(3)); // 79 console.log(“str.charCodeAt(4) 为:” + str.charCodeAt(4)); // 79 console.log(“str.charCodeAt(5) 为:” + str.charCodeAt(5)); // 66 |
3. | concat()连接两个或更多字符串,并返回新的字符串。 | var str1 = new String( “RUNOOB” ); var str2 = new String( “GOOGLE” ); var str3 = str1.concat( str2 ); console.log("str1 + str2 : "+str3) // RUNOOBGOOGLE |
4. | indexOf()返回某个指定的字符串值在字符串中首次出现的位置。 | var str1 = new String( “RUNOOB” ); var index = str1.indexOf( “OO” ); console.log(“查找的字符串位置 :” + index ); // 3 |
5. | lastIndexOf()从后向前搜索字符串,并从起始位置(0)开始计算返回字符串最后出现的位置。 | var str1 = new String( “This is string one and again string” ); var index = str1.lastIndexOf( “string” ); console.log(“lastIndexOf 查找到的最后字符串位置 :” + index ); // 29 index = str1.lastIndexOf( “one” ); console.log(“lastIndexOf 查找到的最后字符串位置 :” + index ); // 15 |
6. | localeCompare()用本地特定的顺序来比较两个字符串。 | var str1 = new String( “This is beautiful string” ); var index = str1.localeCompare( “This is beautiful string”); console.log(“localeCompare first :” + index ); // 0 |
7. | **match()**查找找到一个或多个正则表达式的匹配。 | var str=“The rain in SPAIN stays mainly in the plain”; var n=str.match(/ain/g); // ain,ain,ain |
8. | replace()替换与正则表达式匹配的子串 | var re = /(\w+)\s(\w+)/; var str = “zara ali”; var newstr = str.replace(re, “$2, $1”); console.log(newstr); // ali, zara |
9. | search()检索与正则表达式相匹配的值 | var re = /apples/gi; var str = “Apples are round, and apples are juicy.”; if (str.search(re) == -1 ) { console.log(“Does not contain Apples” ); } else { console.log(“Contains Apples” ); } |
10. | slice()提取字符串的片断,并在新的字符串中返回被提取的部分。 | |
11. | split()把字符串分割为子字符串数组。 | var str = “Apples are round, and apples are juicy.”; var splitted = str.split(" ", 3); console.log(splitted) // [ ‘Apples’, ‘are’, ‘round,’ ] |
12. | substr()从起始索引号提取字符串中指定数目的字符。 | |
13. | substring()提取字符串中两个指定的索引号之间的字符。 | var str = “RUNOOB GOOGLE TAOBAO FACEBOOK”; console.log("(1,2): " + str.substring(1,2)); // U console.log("(0,10): " + str.substring(0, 10)); // RUNOOB GOO console.log("(5): " + str.substring(5)); // B GOOGLE TAOBAO FACEBOOK |
14. | toLocaleLowerCase()根据主机的语言环境把字符串转换为小写,只有几种语言(如土耳其语)具有地方特有的大小写映射。 | var str = “Runoob Google”; console.log(str.toLocaleLowerCase( )); // runoob google |
15. | toLocaleUpperCase()据主机的语言环境把字符串转换为大写,只有几种语言(如土耳其语)具有地方特有的大小写映射。 | var str = “Runoob Google”; console.log(str.toLocaleUpperCase( )); // RUNOOB GOOGLE |
16. | toLowerCase()把字符串转换为小写。 | var str = “Runoob Google”; console.log(str.toLowerCase( )); // runoob google |
17. | toString()返回字符串。 | var str = “Runoob”; console.log(str.toString( )); // Runoob |
18. | toUpperCase()把字符串转换为大写。 | var str = “Runoob Google”; console.log(str.toUpperCase( )); // RUNOOB GOOGLE |
19. | valueOf()返回指定字符串对象的原始值。 | var str = new String(“Runoob”); console.log(str.valueOf( )); // Runoob |
第九节 Array 对象
声明数组有两种方式:
var arr:number[] = [1,2,3];
var arr2:number[] = new Array(4);//长度为4
var arr3:number[] = new Array(1,2,3,4);//初始化
数组解构(解构赋值)
把数组元素赋值给变量。
var arr:number[] = [12,13]
var[x,y] = arr // 将数组的两个元素赋值给变量 x 和 y
console.log(x)
console.log(y)
数组迭代(遍历数组)
var j:any;
var nums:number[] = [1001,1002,1003,1004]
for(j in nums) {
console.log(nums[j])
}
多维数组
一个数组的元素可以是另外一个数组,这样就构成了多维数组(Multi-dimensional Array)。
var multi:number[][] = [[1,2,3],[23,24,25]]
console.log(multi[0][0])
console.log(multi[0][1])
console.log(multi[0][2])
console.log(multi[1][0])
console.log(multi[1][1])
console.log(multi[1][2])
此外,数组还可以作为函数的参数及返回值。
数组方法
序号 | 方法 & 描述 | 实例 |
---|---|---|
1. | concat()连接两个或更多的数组,并返回结果。 | var alpha = [“a”, “b”, “c”]; var numeric = [1, 2, 3]; var alphaNumeric = alpha.concat(numeric); console.log("alphaNumeric : " + alphaNumeric ); // a,b,c,1,2,3 |
2. | every()检测数值元素的每个元素是否都符合条件。 | function isBigEnough(element, index, array) {
return (element >= 10); } var passed = [12, 5, 8, 130, 44].every(isBigEnough); console.log("Test Value : " + passed ); // false |
3. | filter()检测数值元素,并返回符合条件所有元素的数组。 | function isBigEnough(element, index, array) {
return (element >= 10); } var passed = [12, 5, 8, 130, 44].filter(isBigEnough); console.log("Test Value : " + passed ); // 12,130,44 |
4. | forEach()数组每个元素都执行一次回调函数。 | let num = [7, 8, 9]; num.forEach(function (value) { console.log(value); }); |
5. | indexOf()搜索数组中的元素,并返回它所在的位置。如果搜索不到,返回值 -1,代表没有此项。 | var index = [12, 5, 8, 130, 44].indexOf(8); console.log("index is : " + index ); // 2 |
6. | join()把数组的所有元素放入一个字符串。 | var arr = new Array(“Google”,“Runoob”,“Taobao”); var str = arr.join(); console.log(“str : " + str ); // Google,Runoob,Taobao var str = arr.join(”, "); console.log(“str : " + str ); // Google, Runoob, Taobao var str = arr.join(” + "); console.log("str : " + str ); // Google + Runoob + Taobao |
7. | lastIndexOf()返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。 | var index = [12, 5, 8, 130, 44].lastIndexOf(8); console.log("index is : " + index ); // 2 |
8. | map()通过指定函数处理数组的每个元素,并返回处理后的数组。 | var numbers = [1, 4, 9]; var roots = numbers.map(Math.sqrt); console.log("roots is : " + roots ); // 1,2,3 |
9. | pop()删除数组的最后一个元素并返回删除的元素。 | var numbers = [1, 4, 9]; var element = numbers.pop(); console.log("element is : " + element ); // 9 var element = numbers.pop(); console.log("element is : " + element ); // 4 |
10. | push()向数组的末尾添加一个或更多元素,并返回新的长度。 | var numbers = new Array(1, 4, 9); var length = numbers.push(10); console.log("new numbers is : " + numbers ); // 1,4,9,10 length = numbers.push(20); console.log("new numbers is : " + numbers ); // 1,4,9,10,20 |
11. | reduce()将数组元素计算为一个值(从左到右)。 | var total = [0, 1, 2, 3].reduce(function(a, b){ return a + b; }); console.log("total is : " + total ); // 6 |
12. | reduceRight()将数组元素计算为一个值(从右到左)。 | var total = [0, 1, 2, 3].reduceRight(function(a, b){
return a + b; }); console.log("total is : " + total ); // 6 |
13. | reverse()反转数组的元素顺序。 | var arr = [0, 1, 2, 3].reverse(); console.log("Reversed array is : " + arr ); // 3,2,1,0 |
14. | shift()删除并返回数组的第一个元素。 | var arr = [10, 1, 2, 3].shift(); console.log("Shifted value is : " + arr ); // 10 |
15. | slice()选取数组的的一部分,并返回一个新数组。 | var arr = [“orange”, “mango”, “banana”, “sugar”, “tea”]; console.log("arr.slice( 1, 2) : " + arr.slice( 1, 2) ); // mango console.log("arr.slice( 1, 3) : " + arr.slice( 1, 3) ); // mango,banana |
16. | some()检测数组元素中是否有元素符合指定条件。 | function isBigEnough(element, index, array) {
return (element >= 10); } var retval = [2, 5, 8, 1, 4].some(isBigEnough); console.log("Returned value is : " + retval ); // false var retval = [12, 5, 8, 1, 4].some(isBigEnough); console.log("Returned value is : " + retval ); // true |
17. | sort()对数组的元素进行排序。 | var arr = new Array(“orange”, “mango”, “banana”, “sugar”); var sorted = arr.sort(); console.log("Returned string is : " + sorted ); // banana,mango,orange,sugar |
18. | splice()从数组中添加或删除元素。 | var arr = [“orange”, “mango”, “banana”, “sugar”, “tea”]; var removed = arr.splice(2, 0, “water”); console.log("After adding 1: " + arr ); // orange,mango,water,banana,sugar,tea console.log("removed is: " + removed); removed = arr.splice(3, 1); console.log("After removing 1: " + arr ); // orange,mango,water,sugar,tea console.log("removed is: " + removed); // banana |
19. | toString()把数组转换为字符串,并返回结果。 | var arr = new Array(“orange”, “mango”, “banana”, “sugar”); var str = arr.toString(); console.log("Returned string is : " + str ); // orange,mango,banana,sugar |
20. | unshift()向数组的开头添加一个或更多元素,并返回新的长度。 | var arr = new Array(“orange”, “mango”, “banana”, “sugar”); var length = arr.unshift(“water”); console.log("Returned array is : " + arr ); // water,orange,mango,banana,sugar cons |
第十节 Map 对象
Map 对象保存键值对,并且能够记住键的原始插入顺序。
任何值(对象或者原始值) 都可以作为一个键或一个值。
创建Map
TypeScript 使用 Map 类型和 new 关键字来创建 Map:
let myMap = new Map();
初始化 Map,可以以数组的格式来传入键值对:
let myMap = new Map([
["key1", "value1"],
["key2", "value2"]
]);
Map 相关的函数与属性:
- map.clear() – 移除 Map 对象的所有键/值对 。
- map.set() – 设置键值对,返回该 Map 对象。
- map.get() – 返回键对应的值,如果不存在,则返回 undefined。
- map.has() – 返回一个布尔值,用于判断 Map 中是否包含键对应的值。
- map.delete() – 删除 Map 中的元素,删除成功返回 true,失败返回 false。
- map.size – 返回 Map 对象键/值对的数量。
- map.keys() - 返回一个 Iterator 对象, 包含了 Map 对象中每个元素的键 。
- map.values() – 返回一个新的Iterator对象,包含了Map对象中每个元素的值 。
let nameSiteMapping = new Map();
//设置Map 对象
nameSiteMapping.set("test1",1);
nameSiteMapping.set("test2",2);
nameSiteMapping.set("test3",3);
//获取键对应的值
console.log(nameSiteMapping.get("test1"));//1
//判断Map中是否包含某个键对应的值
consolr.log(nameSiteMapping.has("test1"));//true
//返回Map对象键值的数量
console.log(nameSiteMapping.size);//3
//删除某个键值
console.log(nameSiteMapping.delete("test2"));
//移除Map对象的所有键值对
console.log(nameSiteMapping.clear());
迭代Map对象
let nameSiteMapping = new Map();
nameSiteMapping.set("Google", 1);
nameSiteMapping.set("Runoob", 2);
nameSiteMapping.set("Taobao", 3);
// 迭代 Map 中的 key
for (let key of nameSiteMapping.keys()) {
console.log(key);
}
// 迭代 Map 中的 value
for (let value of nameSiteMapping.values()) {
console.log(value);
}
// 迭代 Map 中的 key => value
for (let entry of nameSiteMapping.entries()) {
console.log(entry[0], entry[1]);
}
// 使用对象解析
for (let [key, value] of nameSiteMapping) {
console.log(key, value);
}
第十一节 元组
我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。
元组中允许存储不同类型的元素,元组可以作为参数传递给函数。
初始化
声明一个元组并初始化:
var mytuple = [10,"Runoob"];
或者我们可以先声明一个空元组,然后再初始化:
var mytuple = [];
mytuple[0] = 120
mytuple[1] = 234
访问元组
与访问数组一个样儿.
var mytuple = [10,"Runoob"]; // 创建元组
console.log(mytuple[0])
console.log(mytuple[1])
元组运算
我们可以使用以下两个函数向元组添加新元素或者删除元素:
- push() 向元组添加元素,添加在最后面。
- pop() 从元组中移除元素(最后一个),并返回移除的元素。
var mytuple = [10,"Hello","World","typeScript"];
console.log("添加前元素个数:"+mytuple.length);//4 // 返回元组的大小
mytuple.push(12) // 添加到元组中
console.log("添加后元素个数:"+mytuple.length);//5
console.log("删除前元素个数:"+mytuple.length);//5
console.log(mytuple.pop()+" 元素从元组中删除");//12 // 删除并返回删除的元素
console.log("删除后元素个数:"+mytuple.length);//4
更新元组
var mytuple = [10, "Runoob", "Taobao", "Google"]; // 创建一个元组
console.log("元组的第一个元素为:" + mytuple[0])
// 更新元组元素
mytuple[0] = 121
console.log("元组中的第一个元素更新为:"+ mytuple[0]);//121
解构元组
var a =[10,"Runoob"]
var [b,c] = a
console.log( b );//10
console.log( c );//Runoob
第十二节 联合类型
联合类型(Union Types)可以通过管道(|)将变量设置多种类型,赋值时可以根据设置的类型来赋值。
注意:只能赋值指定的类型,如果赋值其它类型就会报错。
创建联合类型的语法格式如下:
Type1|Type2|Type3
val 变量只能接受string和number两种数据类型 否则会报错:
var val:string|number
val = 12
console.log("数字为 "+ val)
val = "Runoob"
console.log("字符串为 " + val)
也可以将联合类型作为函数参数使用:
function disp(name:string|string[]) {
if(typeof name == "string") {
console.log(name)
} else {
var i;
for(i = 0;i<name.length;i++) {
console.log(name[i])
}
}
}
disp("Runoob")
console.log("输出数组....")
disp(["Runoob","Google","Taobao","Facebook"])
联合类型数组
顾名思义,就是把数组声明为联合类型。
var arr:number[]|string[];
var i:number;
arr = [1,2,4]
console.log("**数字数组**")
for(i = 0;i<arr.length;i++) {
console.log(arr[i])
}
arr = ["Runoob","Google","Taobao"]
console.log("**字符串数组**")
for(i = 0;i<arr.length;i++) {
console.log(arr[i])
}
第十三节 接口
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。
定义如下:
interface interface_name {
}
//定义了一个接口
interface IPerson {
firstName:string,
lastName:string,
sayHi: ()=>string
}
var customer:IPerson = {
firstName:"Tom",
lastName:"Hanks",
sayHi: ():string =>{
return "Hi there"}
}
console.log("Customer 对象 ")
console.log(customer.firstName)
console.log(customer.lastName)
console.log(customer.sayHi())
var employee:IPerson = {
firstName:"Jim",
lastName:"Blakes",
sayHi: ():string =>{
return "Hello!!!"}
}
console.log("Employee 对象 ")
console.log(employee.firstName)
console.log(employee.lastName)
**注意:**需要注意接口不能转换为Javascript,它只是TS的一部分。
联合类型和接口
interface RunOptions {
program:string;
commandline:string[]|string|(()=>string);
}
// commandline 是字符串
var options:RunOptions = {
program:"test1",commandline:"Hello"};
console.log(options.commandline)
// commandline 是字符串数组
options = {
program:"test1",commandline:["Hello","World"]};
console.log(options.commandline[0]);
console.log(options.commandline[1]);
// commandline 是一个函数表达式
options = {
program:"test1",commandline:()=>{
return "**Hello World**";}};
var fn:any = options.commandline;
console.log(fn());
接口和数组
接口中我们可以将数组的索引值和元素设置为不同类型,索引值可以是数字或字符串。
interface namelist {
[index:number]:string
}
var list2:namelist = ["John",1,"Bran"] // 错误元素 1 不是 string 类型
interface ages {
[index:string]:number
}
var agelist:ages;
agelist["John"] = 15 // 正确
agelist[2] = "nine" // 错误
接口继承
接口继承就是说接口可以通过其他接口来扩展自己。
Typescript 允许接口继承多个接口。
继承使用关键字 extends。
单接口继承语法格式:
Child_interface_name extends super_interface_name
多接口继承语法格式:
Child_interface_name extends super_interface1_name, super_interface2_name,…,super_interfaceN_name
继承的各个接口使用逗号 , 分隔。
单继承
interface Person {
age:number
}
interface Musician extends Person {
instrument:string
}
var drummer = <Musician>{
};
drummer.age = 27
drummer.instrument = "Drums"
console.log("年龄: "+drummer.age)
console.log("喜欢的乐器: "+drummer.instrument)
多继承
interface IParent1 {
v1:number
}
interface IParent2 {
v2:number
}
interface Child extends IParent1, IParent2 {
}
var Iobj:Child = {
v1:12, v2:23}
console.log("value 1: "+Iobj.v1+" value 2: "+Iobj.v2)
第十四节 类
TypeScript 是面向对象的 JavaScript。
类描述了所创建的对象共同的属性和方法。
TypeScript 支持面向对象的所有特性,比如 类、接口等。
TypeScript 类定义方式如下:
class class_name {
// 类作用域
}
定义类的关键字为 class,后面紧跟类名,类可以包含以下几个模块(类的数据成员):
- 字段 − 字段是类里面声明的变量。字段表示对象的有关数据。
- 构造函数 − 类实例化时调用,可以为类的对象分配内存。
- 方法 − 方法为对象要执行的操作。
创建类的数据成员
以下实例我们声明了类 Car,包含字段为 engine,构造函数在类实例化后初始化字段 engine。
this 关键字表示当前类实例化的对象。注意构造函数的参数名与字段名相同,this.engine 表示类的字段。
此外我们也在类中定义了一个方法 disp()。
class Car {
// 字段
engine:string;
// 构造函数
constructor(engine:string) {
this.engine = engine
}
// 方法
disp():void {
console.log("发动机为 : "+this.engine)
}
}
实例化对象
我们使用 new 关键字来实例化类的对象,语法格式如下:
var object_name = new class_name([ arguments ])
类实例化时会调用构造函数,例如:
var obj = new Car("Engine 1")
类中的字段属性和方法可以使用 . 号来访问:
// 访问属性
obj.field_name
// 访问方法
obj.function_name()
案例:
class Car {
// 字段
engine:string;
// 构造函数
constructor(engine:string) {
this.engine = engine
}
// 方法
disp():void {
console.log("函数中显示发动机型号 : "+this.engine);// XXSY1
}
}
// 创建一个对象
var obj = new Car("XXSY1")
// 访问字段
console.log("读取发动机型号 : "+obj.engine);// XXSY1
// 访问方法
obj.disp()
类的继承
TypeScript 支持继承类,即我们可以在创建类的时候继承一个已存在的类,这个已存在的类称为父类,继承它的类称为子类。
类继承使用关键字 extends,子类除了不能继承父类的私有成员(方法和属性)和构造函数,其他的都可以继承。
TypeScript 一次只能继承一个类,不支持继承多个类,但 TypeScript 支持多重继承(A 继承 B,B 继承 C)。
语法格式如下:
class child_class_name extends parent_class_name
实例:
类的继承:实例中创建了 Shape 类,Circle 类继承了 Shape 类,Circle 类可以直接使用 Area 属性:
class Shape {
Area:number
constructor(a:number) {
this.Area = a
}
}
class Circle extends Shape {
disp():void {
console.log("圆的面积: "+this.Area)
}
}
var obj = new Circle(223);
obj.disp()
继承类的方法重写
类继承后,子类可以对父类的方法重新定义,这个过程称之为方法的重写。
其中 super 关键字是对父类的直接引用,该关键字可以引用父类的属性和方法。
class PrinterClass {
doPrint():void {
console.log("父类的 doPrint() 方法。")
}
}
class StringPrinter extends PrinterClass {
doPrint():void {
super.doPrint() // 调用父类的函数
console.log("子类的 doPrint()方法。")
}
}
static 关键字
static 关键字用于定义类的数据成员(属性和方法)为静态的,静态成员可以直接通过类名调用。
class StaticMem {
static num:number;
static disp():void {
console.log("num 值为 "+ StaticMem.num)
}
}
StaticMem.num = 12 // 初始化静态变量
StaticMem.disp() // 调用静态方法
instanceof 运算符
instanceof 运算符用于判断对象是否是指定的类型,如果是返回 true,否则返回 false。
class Person{
}
var obj = new Person()
var isPerson = obj instanceof Person;
console.log("obj 对象是 Person 类实例化来的吗? " + isPerson);// true
访问控制修饰符
TypeScript 中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。TypeScript 支持 3 种不同的访问权限。
- public(默认) : 公有,可以在任何地方被访问。
- protected : 受保护,可以被其自身以及其子类和父类访问。
- private : 私有,只能被其定义所在的类访问。
class Encapsulate {
str1:string = "hello"
private str2:string = "world"
}
var obj = new Encapsulate()
console.log(obj.str1) // 可访问
console.log(obj.str2) // 编译错误, str2 是私有的
类和接口
类可以实现接口,使用关键字 implements,并将 interest 字段作为类的属性使用。
interface ILoan {
interest:number
}
class AgriLoan implements ILoan {
interest:number
rebate:number
constructor(interest:number,rebate:number) {
this.interest = interest
this.rebate = rebate
}
}
var obj = new AgriLoan(10,1)
console.log("利润为 : "+obj.interest+",抽成为 : "+obj.rebate );// 10 1
第十五节 对象
对象是包含一组键值对的实例。 值可以是标量、函数、数组、对象等.
var object_name = {
key1: "value1", // 标量
key2: "value",
key3: function() {
// 函数
},
key4:["content1", "content2"] //集合
}
以上对象包含了标量,函数,集合(数组或元组)。
TS 类型模板
假如我们在 JavaScript 定义了一个对象:
var sites = {
site1:"Runoob",
site2:"Google"
};
这时如果我们想在对象中添加方法,可以做以下修改:
sites.sayHello = function(){
return "hello";
}
如果在 TypeScript 中使用以上方式则会出现编译错误,因为Typescript 中的对象必须是特定类型的实例。
var sites = {
site1: "Runoob",
site2: "Google",
sayHello: function () {
} // 类型模板
};
sites.sayHello = function () {
console.log("hello " + sites.site1);
};
sites.sayHello();
总结:TypeScript 与 JavaScript 的区别
TS是JS的超集,可以在TS中写JS语法。它也是一种强类型、面向对象语言。
总的来说,TS参考了面向对象语言的语法,例如:Java。
相比JS,TS可以对变量进行类型注解,保留了原始变量声明,但在TS中叫做any类型。类型注解可以用在变量、函数、数组等。