因为工作中要用到 angular ,因此需要掌握一点 typescript 的基础。本文总结了 ts 最 常用的知识,对于那些只想上手写 ts ,不愿意花太多时间研究 ts 的人来说值得一看。我本人最初的目的也是记录常用知识点,方便自己查阅。因为作者有 java 的基础,所以文中把编程的一些基本常识省略了,初学编程者不建议看,应该去看更全面的学习资料,打好基础。本文是参考菜鸟教程的 ts 教程总结,代码来源于菜鸟教程,如有侵权,请联系作者删除。
面向过程
变量
ts是js的超集,运行时会先编译成js,js定义变量不需要声明类型,ts需要。ts变量声明时不必立即初始化,声明如下
var [变量名] : [类型] = 值;
基本类型
let decLiteral: number = 6; // 数字
let name: string = "Runoob"; // 字符串
let flag: boolean = true; // 布尔
let arr: number[] = [1, 2]; // 数组
元组
元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。获取元组的元素和Java数组类似
let x: [string, number];
x = ['Runoob', 1]; // 运行正常
console.log(x[0])
枚举
enum Color {Red, Green, Blue};
let c: Color = Color.Blue;
console.log(c); // 输出 2
any
变量的值会动态改变时,比如来自用户的输入,任意值类型可以让这些变量跳过编译阶段的类型检查
let x: any = 1; // 数字类型
x = 'I am who I am'; // 字符串类型
x = false; // 布尔类型
运算符
ts中运算符与java基本一样。
ts中有 - 负号运算符
控制语句
选择语句
ts中的选择语句与java一直,有if if-else if-else if-else,还有switch。
var num:number = 12;
if (num % 2==0) {
console.log("偶数");
} else {
console.log("奇数");
}
循环语句
基本for
var num:number = 5;
var factorial = 1;
for(var i:number = num;i>=1;i--) {
factorial *= i;
}
// 遍历数组
let someArray = [1, 10, 12];
for (var i:number=0;i<3;i++) {
console.log(someArray[i]); // 1, "string", false
}
for in, for in 循环的是键,例如输出字符串的每个字符,j 是下标
var j:any;
var n:any = "a b c"
for(j in n) {
console.log(n[j]) // 输出换行的a b c
}
for of , 遍历元组,此处用 in 会出错,因为 in 取得是下标
let someArray = [1, "string", false];
for (let entry of someArray) {
console.log(entry); // 1, "string", false
}
foreach,传入的是一个回调函数,不支持跳出循环
var myArray:number[]=[1,2,3,4];
myArray.forEach(value => {console.log(value)}); //1,2,3,4
//break 在forEach不支持,不允许挑出循环
every,支持跳出循环
let list = [4, 5, 6];
list.every((val, idx, array) => {
// val: 当前值, idx:当前index, array: Array
console.log(val + " "+idx); //三个参数都是可选参数
return true; // Continues
// Return false will quit the iteration
});
while
while(condition) {
statement(s);
}
do-while
do {
statement(s);
}while( condition );
函数
方法格式如下
function function_name():return_type {
// 语句
return value;
}
方法可以没有返回类型,此时无返回值,类似 void
// 函数定义
function greet():string { // 返回一个字符串
return "Hello World"
}
function caller() {
var msg = greet() // 调用 greet() 函数
console.log(msg)
}
// 调用函数
caller()
默认参数
rate: number = 0.50
可选参数
rate?: number
字符串
构造方式
var txt:string = "helloworld"
var txt = new 或者更简单方式:
var txt = "string";
属性
constructor,对创建该对象的函数的引用。
var str = new String( "This is string" );
console.log("str.constructor is:" + str.constructor)
// str.constructor is:function String() { [native code] }
length 字符串长度
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)
常用方法
charAt() // 字符
charCodeAt() // 字符的编码
concat() //连接
indexOf() // 索引
lastIndexOf() // 最后一个索引
split() // 分割数组
substr(5,10) // 提取子串,从5开始提取10个
substring(5,10) // 按起始索引提取字符,从5开始提取到下标10
toLowerCase() // 转小写
valueOf() // 返回值指定字符串对象的原始值
正则匹配
优先级较低,先省略
数据结构
数组
数组创建
知道元素,创建数组
var sites:string[];
sites = ["Google","Runoob","Taobao"]
var numlist:number[] = [2,4,6,8]
定长数组,ts中数组也是通过 [i] 下标获取元素
var arr_names:number[] = new Array(4) //注意声明方式中的括号
for(var i = 0; i<arr_names.length; i++) {
arr_names[i] = i * 2
console.log(arr_names[i])
}
二维数组的创建类比java即可,没什么不同。
数组遍历
for(j in nums) {
console.log(nums[j])
}
数组方法
reverse(),反转数组的元素顺序。
pop(),删除数组的最后一个元素并返回删除的元素。
push(),向数组的末尾添加一个或更多元素,并返回新的长度。
shift(),删除并返回数组的第一个元素。
unshift(),向数组的开头添加一个或更多元素,并返回新的长度
sort(),对数组的元素进行排序。
toString(),把数组转换为字符串,并返回结果。好像打印数组默认调用 toString()。
**注意:**上面几个方法可以实现栈和队列这两种常用的线性数据结构,也是最常用的方法,
元素下标
var index = [12, 5, 8, 130, 44].indexOf(8);
var index = [12, 5, 8, 130, 44].lastIndexOf(8);
slice(),选取数组的的一部分,并返回一个新数组。以第一个参数为下标,开始截取,不包括第二个参数指向的元素。
var arr = ["orange", "mango", "banana", "sugar", "tea"];
console.log("arr.slice( 1, 2) : " + arr.slice( 1, 2) ); // mango
concat()
var alpha = ["a", "b", "c"]; // 这个数组和也是元组啊
var numeric = [1, 2, 3];
var alphaNumeric = alpha.concat(numeric);
splice(),从数组中添加或删除元素。3个参数是添加,2个参数是移除。
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
注意:下面的方法都是类似于 java lambda 中的方法,都已 lambda 表达式作为参数。
foreach()。对每一个元素执行回调函数
let num = [7, 8, 9];
num.forEach(function (value) {
console.log(value);
});
join()把数组的所有元素放入一个字符串。
var arr = new Array("Google","Runoob","Taobao");
var str = arr.join();
console.log("str : " + str ); // Google,Runoob,Taobao
map(),通过指定函数处理数组的每个元素,并返回处理后的数组,这个有点像 java 的lambda表达式中的 map。
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
console.log("roots is : " + roots ); // 1,2,3
filter(),检测数值元素,并返回符合条件所有元素的数组。这与 java lambda 中的filter() 方法类似。匿名函数中的三个参数固定写即可,别纠结。filter方法返回值类型一般为boolean,如果为false的话,元素就会被过滤掉。
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
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
reduce(),将数组元素计算为一个值(从左到右),这与 Java lambda中的约简操作类似。需要的参数都是回调函数。
var total = [0, 1, 2, 3].reduce(function(a, b){ return a + b; });
console.log("total is : " + total ); // 6
元组
我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。
创建元组
var mytuple = [10,"Runoob"]; // 方式1
var mytuple = []; // 方式2
mytuple[0] = 120
mytuple[1] = 234
元组的访问与数组类似,都是通过索引,并且元组元素可变。
操作元组
我们可以使用以下两个函数向元组添加新元素或者删除元素:
- push() 向元组添加元素,添加在最后面。
- pop() 从元组中移除元素(最后一个),并返回移除的元素。
解构元组
通过解构可以把元组直接复制给单个变量,数组也具有解构的特性。感觉 ts 的这个特性多次,单个赋值也挺好。
var a =[10,"Runoob"]
var [b,c] = a
console.log( b )
console.log( c )
Map
Map 对象保存键值对,并且能够记住键的原始插入顺序。可类比java总Map来使用。
创建Map
let myMap = new 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对象中每个元素的值 。
遍历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);
}
Json
全称JavaScript Object Notation,待补充
面向对象
接口
ts接口中可以有方法和属性,这些方法都应该是抽象的,需要由具体的变量去实现。用户以接口为模板创建变量时,不仅需要实现方法,还需要对变量初始化。
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())
注意 js 中没有接口。
接口和类中定义的方法前面没有 function 关键字,但可以有 private 等修饰符。我在angular10 中方法前加 function 会编译错误,这里的方法和我在angular10中见的就一样了。要把方法和前面的函数区别开来。
类
类和前面的接口不同的地方在于类中会实现方法,而接口中不会实现方法。调用类的构造函数可以创建一个对象,不用关心实现其它的;而以接口创建变量时,每创建一个,就得实现接口中定义的所有的东西,麻烦啊!
class Car {
// 字段
engine:string;
// 构造函数
constructor(engine:string) {
this.engine = engine
}
// 方法
disp():void {
console.log("函数中显示发动机型号 : "+this.engine)
}
}
// 创建一个对象
var obj = new Car("XXSY1")
// 访问字段
console.log("读取发动机型号 : "+obj.engine)
// 访问方法
obj.disp()
封装
TypeScript 支持 3 种不同的访问权限。
- public(默认) : 公有,可以在任何地方被访问。
- protected : 受保护,可以被其自身以及其子类和父类访问。
- private : 私有,只能被其定义所在的类访问。
继承
与Java 一样,继承用关键字 extends,继承之后也可以对方法进行重写。
模块
模块是在其自身的作用域里执行,并不是在全局作用域,这意味着定义在模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。
在 angular10 中,通常把一个类作为一个模块。ts 文件中的类前加 export,angular10 的其它组件就能通过 import 引入该组件了。