TypeScript
Typescript简介
-
TypeScript是JavaScript类型的超集(当前我们处于ES5),它可以编译成纯JavaScript。
-
TypeScript给JavaScript加上可选的类型系统,给JavaScript加上静态类型后,就能将调试从运行期提前到编码期,诸如类型检查、越界检查这样的功能才能真正发挥作用。 TypeScript的开发体验远远超过以往纯JavaScript的开发体验,无需运行程序即可修复潜在bug。
Typescript语法
let 和 const
-
不使用var,使用let或const申明变量,并加上类型说明,且作用域为块级即以{}为界
-
let lang: string = ‘TypeScript’;//如果省略类型说明,TS也可进行自动推断
-
lang = 1010;//error! 如果需要可以使用联合类型:let lang: number | string = ‘TS’;
-
let age: number = 89;
-
let age = 64;//error!
-
const pi: number = 3.14159;//pi以后不可改变,类似常量
-
pi = 3.14;//error!
解构
- 将对象、数组中的元素拆分到指定变量中,以方便使用
- //解构数组
- let input = [89, 64, 2018, 10];
- let [first, second] = input;//注意使用[]
- console.log(first); // 89
- console.log(second); // 64
- let [one, …others] = input; //剩余变量
- console.log(…others);
- //展开
- let newArr = [89, …others, 18];
- console.log(newArr);
- //解构对象
- let o = {
- a: “foo”,
- b: 12,
- c: “bar”
- };
- let {a, b} = o;//注意使用{},且变量名需与对象中道属性名一致
- console.log(a, b);
函数
完整函数类型定义
- //命名函数,有完整的参数和返回类型。可以不用,TS将自动进行类型推断但推荐使用!
- function add(x: number, y: number): number {
- return x + y;
- }
- //匿名函数
- let myAdd = function(x: number, y: number): number { return x + y; };
- console.log(myAdd(1, ‘2’));//error
- console.log(myAdd(1));//error
- console.log(typeof myAdd(1, 2));//number
可选参数
- //可选参数,必须放在必要参数后
- function greeting(firstName: string, lastName?: string) {
- if(lastName)
- return
Hello ${firstName} ${lastName}!
; - }
- return
Hello ${firstName}!
; - }
- console.log(greeting(‘QiGe’));
- console.log(greeting(‘QiGe’, ‘Wang’));
- console.log(greeting(‘QiGe’, ‘Wang’, ‘Yong’));//error!
默认参数
- //默认参数,不必在必要参数后
- function greeting(firstName: string, lastName = ‘Wang’) {
- return
Hello ${firstName} ${lastName}!
; - }
- console.log(greeting(‘QiGe’));
- console.log(greeting(‘QiGe’, ‘HaHaHa’));
- console.log(greeting(‘QiGe’, ‘HaHaHa’, ‘Yong’));//error!
剩余参数
- 必要参数,默认参数和可选参数有个共同点:它们表示某一个参数。 有时,你想同时操作多个参数,或者你并不知道会有多少参数传递进来, 在TypeScript里,你可以把所有参数收集到一个变量里
- //剩余参数,会被当做个数不限的可选参数。可以一个都没有,也可以有任意个
- function greeting(firstName: string, …restName: string[]) {
- return
Hello ${firstName} ${restName.join(' ')}!
; - }
- console.log(greeting(‘Osama’, ‘bin’, ‘Muhammad’, ‘bin’, ‘Awad’, ‘bin’, ‘Laden’));
- console.log(greeting(‘Laden’));
箭头函数
- 特点:简化函数定义、解决this问题
- //无参数,函数体代码只有一行,则该行结果即为函数返回值
- let greeting1 = () =>
Hello TS!
; - console.log(greeting1());
- //一个参数,函数体代码只有一行,则该行结果即为函数返回值
- let greeting2 = (name: string) =>
Hello ${name}
; - console.log(greeting2(‘QiGe’));
- //两个及以上的参数,函数体代码只有一行,则该行结果即为函数返回值
- let add1 = (n1: number, n2: number) => n1 + n2;
- console.log(add1(1, 2));
- //两个及以上的参数,函数体代码多于一行,则必须用{}包裹,且显式给出return
- let add2 = (n1: number, n2: number) => {
- let sum = n1 + n2;
- return sum;//改为sum++结果如何?
- }
- console.log(add2(1, 2));
类class
类的定义和使用
- 类是属性(有些什么)和函数(能干什么)的集合,是生成对象(Object)或类实例的模板。
- //类的定义和使用
- class MyInfo { //class是关键字,类名默认全部大写首字母
- name: string; //属性
- weather: string; //属性
- constructor(name: string, weather: string){ //构造函数,一般用于初始化。如果没有,TS会自动生成一个,以备用new创建类实例时调用。
- this.name = name;
- this.weather = weather;
- }
- printInfo(): void { //其它函数,无返回值
- console.log(
Hello, ${this.name}.
); - console.log(
Today is ${this.weather}.
); - }
- }
- let myData = new MyInfo(‘QiGe’, ‘raining’); //使用new关键字生成对象,即该类的实例
- myData.printInfo();
类的属性和函数的访问权限
- 类中的属性和函数都有访问权限,默认为public即全局可访问,其次为protected即可在类的内部和其子类的内部可访问,最后为private,只能在该类内部可访问。
- //访问权限
- class MyInfo { //class是关键字,类名默认全部大写首字母
- public name: string; //public属性,可省略
- private _weather: string; //私有属性,习惯以_开头进行命名
- constructor(name: string, weather: string){ //构造函数,一般用于初始化
- this.name = name;
- this._weather = weather;
- }
- printInfo(): void { //其它函数
- this._test();
- console.log(
Hello, ${this.name}.
); - console.log(
Today is ${this._weather}.
); - }
- private _test(): void {
- console.log(‘You can not call me outside!’);
- }
- }
- let myData = new MyInfo(‘QiGe’, ‘raining’); //使用new关键字生成对象
- console.log(myData._weather); //error!
- myData._test(); //error
- myData.printInfo();
存取器-getter、setter
- 当在类外部时,建议设置getter和setter操作其private属性,即使public属性也如此。
- //getter和setter
- class MyInfo { //class是关键字,类名默认全部大写首字母
- private readonly _name: string; //私有属性,外部不可访问。readonly使其只能在初始化时赋值,以后不可更改。
- private _weather: string; //私有属性,习惯以_开头进行命名
- constructor(name: string, weather: string){ //构造函数,一般用于初始化
- this._name = name;
- this._weather = weather;
- }
- get name(): string {
- return this._name;
- }
- set name(value: string) { //error! _name有readonly属性
- this._name = value;
- }
- get weather(): string {
- return this._weather;
- }
- set weather(value: string) {
- this._weather = value;
- }
- }
- let myData = new MyInfo(‘QiGe’, ‘raining’); //使用new关键字生成对象
- console.log(myData.name, myData.weather);
- myData.weather = ‘sunny’; //OK
- myData.name = ‘Wang’; //error!
- console.log(myData);
静态属性
- 类中的属性或函数有static修饰,则可直接使用而不需要实例化
- //静态属性,内建或自定义,无需new即可使用
- console.log(Math.round(89.64)); //90
- console.log(Math.pow(2, 8)); //256
- class MyStaticClass {
- static place = ‘Earth’;
- static printInfo() {
- console.log(‘We have only one Earth!’);
- }
- }
- console.log(MyStaticClass.place);
- MyStaticClass.printInfo();
继承
- 可以通过extends关键字继承其它类,从而成为其子类
- class Animal {
- // 当构造函数传入的参数加上了“访问权限控制符”,则同时会声明同名类属性,并赋值
- constructor(public name: string) { }
- protected log(message: string) {
- console.log(message);
- }
- move(distanceInMeters: number = 0) {
- this.log(
${this.name} moved ${distanceInMeters}m.
);//请注意name来自何处 - this.log(‘==============’);
- }
- }
- class Horse extends Animal {
- constructor(name: string) {
- super(name); // 通过super调用父类构造器
- }
- run(distanceInMeters = 50) { //自己独有的函数
- this.log(“Clop, clop…”);
- super.move(distanceInMeters); // 通过super调用父类方法
- }
- }
- class Eagle extends Animal {
- constructor(name: string) { super(name); }
- reborn() { //自己独有的函数
- console.log(‘Reborn? It is a joke, hahaha!’);
- }
- }
- let tom: Horse = new Horse(“Tommy the Palomino”);
- tom.run(8964);
- let sam: Eagle = new Eagle(“Sammy the Hawk”);
- sam.move(1024);//sam的move函数来自何处?
- sam.reborn();
模块Module
- 对于大型的项目,我们需要使用模块进行管理。每个 .ts 文件就是一个模块,通过 export 来对外部模块暴露元素,通过 import 来引入模块。
- export class Name { //用export对外部暴露该类
- constructor(private first: string, private second: string) {}
- get nameMessage() {
- return
Hello ${this.first} ${this.second}
; - }
- }
- export class WeatherLocation { //用export对外部暴露该类
- constructor(private weather: string, private city:string) {}
- get weatherMessage() {
- return
It is ${this.weather} in ${this.city}
; - }
- }
- //用import从外部模块文件导入,默认后缀.ts去掉
- import { Name } from “./modules/name”;
- import { WeatherLocation } from “./modules/weather”;
- let name = new Name(‘Wang’, ‘Yong’);
- let loc = new WeatherLocation(‘raining’, ‘ChongQing’);
- console.log(name.nameMessage);
- console.log(loc.weatherMessage);