TypeScript
建议先学JavaScript再看TypeScript,这样你就会很快的理解。
文章目录
TypeScript第一节 基础类型第二节 变量声明类型断言类型推断变量作用域
第三节 运算符算术运算符关系运算符逻辑运算符短路运算符(&& 与 ||)位运算符赋值运算符三元运算符(? :)类型运算符typeof 运算符instanceof 运算符
其它运算符负号运算符(-)字符串运算符:连接运算符(+)
第四节 条件语句if 语句if...else 语句if...else if...else 语句switch...case 语句
第五节 循环for 循环语法实例
for...in 循环for…of 、forEach、every 和 some 循环while 循环语法
do...while 循环语法
break 语句continue 语句
第六节 函数调用函数函数返回值带参数函数可选参数默认参数剩余参数匿名函数匿名函数自调用
构造函数递归函数箭头函数函数重载参数类型不同:参数数量不同:参数类型顺序不同:
第七节 Number 对象Number 对象属性Number 对象方法
第八节 String 对象String 对象属性String 对象方法
第九节 Array 对象数组解构(解构赋值)数组迭代(遍历数组)多维数组数组方法
第十节 Map 对象创建Map迭代Map对象
第十一节 元组初始化访问元组元组运算更新元组解构元组
第十二节 联合类型联合类型数组
第十三节 接口联合类型和接口接口和数组接口继承单继承多继承
第十四节 类创建类的数据成员实例化对象类的继承继承类的方法重写static 关键字instanceof 运算符访问控制修饰符类和接口
第十五节 对象TS 类型模板
总结:TypeScript 与 JavaScript 的区别
第一节 基础类型
数据类型关键字描述任意类型anyany类型变量可以被赋予任意类型的值数据类型number可被赋予任意进制数、整数、分数字符串类型string可使用单引号、双引号、反引号布尔类型booleantrue、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.Bluevoidvoid表示返回值类型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 =
类型推断
当类型没有给出时,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==8false!=不等于5!=8true>大于5>8false<小于5<8true>=大于或等于5>=8false<=小于或等于5<=8true
逻辑运算符
逻辑运算符用于测定变量或值直接的逻辑。
给定 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 & 10101 & 000100011|OR,按位或处理两个长度相同的二进制数,两个相应的二进位中只要有一个为 1,该位的结果值为 1。x = 5 | 10101 | 000101015~取反,取反是一元运算符,对一个二进制数的每一位执行逻辑反操作。使数字 1 成为 0,0 成为 1。x = ~ 5~01011010-6^异或,按位异或运算,对等长二进制模式按位或二进制数的每一位执行逻辑异按位或操作。操作的结果是如果某位不同则该位为 1,否则该位为 0。x = 5 ^ 10101 ^ 000101004<<左移,把 << 左边的运算数的各二进位全部左移若干位,由 << 右边的数指定移动的位数,高位丢弃,低位补 0。x = 5 << 10101 << 1101010>>右移,把 >> 左边的运算数的各二进位全部右移若干位,>> 右边的数指定移动的位数。x = 5 >> 10101 >> 100102>>>无符号右移,与有符号右移位类似,除了左边一律使用0 补位。x = 2 >>> 10010 >>> 100011
赋值运算符
赋值运算符用于给变量赋值。
给定 x=10 和 y=5,下面的表格解释了赋值运算符:
运算符例子实例x 值= (赋值)x = yx = yx = 5+= (先进行加运算后赋值)x += yx = x + yx = 15-= (先进行减运算后赋值)x -= yx = x - yx = 5*= (先进行乘运算后赋值)x *= yx = x * yx = 50/= (先进行除运算后赋值)x /= yx = x / yx = 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 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+32.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.2340003.toLocaleString()把数字转换为字符串,使用本地数字格式顺序。var num = new Number(177.1234); console.log( num.toLocaleString()); // 输出:177.12344.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.15.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进制:126.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) // 输出 113.prototype允许您向对象添加属性和方法。function employee(id:number,name:string) { this.id = id this.name = name } var emp = new employee(123,“admin”) employee.prototype.email=“admin@runoob.com” // 添加属性 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)); // B2.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)); // 663.concat()连接两个或更多字符串,并返回新的字符串。var str1 = new String( “RUNOOB” ); var str2 = new String( “GOOGLE” ); var str3 = str1.concat( str2 ); console.log("str1 + str2 : "+str3) // RUNOOBGOOGLE4.indexOf()返回某个指定的字符串值在字符串中首次出现的位置。var str1 = new String( “RUNOOB” ); var index = str1.indexOf( “OO” ); console.log(“查找的字符串位置 :” + index ); // 35.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 ); // 156.localeCompare()用本地特定的顺序来比较两个字符串。var str1 = new String( “This is beautiful string” ); var index = str1.localeCompare( “This is beautiful string”); console.log(“localeCompare first :” + index ); // 07.**match()**查找找到一个或多个正则表达式的匹配。var str=“The rain in SPAIN stays mainly in the plain”; var n=str.match(/ain/g); // ain,ain,ain8.replace()替换与正则表达式匹配的子串var re = /(\w+)\s(\w+)/; var str = “zara ali”; var newstr = str.replace(re, “$2, $1”); console.log(newstr); // ali, zara9.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 FACEBOOK14.toLocaleLowerCase()根据主机的语言环境把字符串转换为小写,只有几种语言(如土耳其语)具有地方特有的大小写映射。var str = “Runoob Google”; console.log(str.toLocaleLowerCase( )); // runoob google15.toLocaleUpperCase()据主机的语言环境把字符串转换为大写,只有几种语言(如土耳其语)具有地方特有的大小写映射。var str = “Runoob Google”; console.log(str.toLocaleUpperCase( )); // RUNOOB GOOGLE16.toLowerCase()把字符串转换为小写。var str = “Runoob Google”; console.log(str.toLowerCase( )); // runoob google17.toString()返回字符串。var str = “Runoob”; console.log(str.toString( )); // Runoob18.toUpperCase()把字符串转换为大写。var str = “Runoob Google”; console.log(str.toUpperCase( )); // RUNOOB GOOGLE19.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,32.every()检测数值元素的每个元素是否都符合条件。function isBigEnough(element, index, array) { return (element >= 10); } var passed = [12, 5, 8, 130, 44].every(isBigEnough); console.log("Test Value : " + passed ); // false3.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,444.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 ); // 26.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 + Taobao7.lastIndexOf()返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。var index = [12, 5, 8, 130, 44].lastIndexOf(8); console.log("index is : " + index ); // 28.map()通过指定函数处理数组的每个元素,并返回处理后的数组。var numbers = [1, 4, 9]; var roots = numbers.map(Math.sqrt); console.log("roots is : " + roots ); // 1,2,39.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 ); // 410.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,2011.reduce()将数组元素计算为一个值(从左到右)。var total = [0, 1, 2, 3].reduce(function(a, b){ return a + b; }); console.log("total is : " + total ); // 612.reduceRight()将数组元素计算为一个值(从右到左)。var total = [0, 1, 2, 3].reduceRight(function(a, b){ return a + b; }); console.log("total is : " + total ); // 613.reverse()反转数组的元素顺序。var arr = [0, 1, 2, 3].reverse(); console.log("Reversed array is : " + arr ); // 3,2,1,014.shift()删除并返回数组的第一个元素。var arr = [10, 1, 2, 3].shift(); console.log("Shifted value is : " + arr ); // 1015.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,banana16.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 ); // true17.sort()对数组的元素进行排序。var arr = new Array(“orange”, “mango”, “banana”, “sugar”); var sorted = arr.sort(); console.log("Returned string is : " + sorted ); // banana,mango,orange,sugar18.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); // banana19.toString()把数组转换为字符串,并返回结果。var arr = new Array(“orange”, “mango”, “banana”, “sugar”); var str = arr.toString(); console.log("Returned string is : " + str ); // orange,mango,banana,sugar20.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 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 console.log(arr[i]) } arr = ["Runoob","Google","Taobao"] console.log("**字符串数组**") for(i = 0;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 = 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类型。类型注解可以用在变量、函数、数组等。