typescript


$ tsc hello.ts将hello.ts 转换为hello.js文件

TypeScript字符串新特性

  • var content = `aaa

    bbb<br>
    ccc\`;<br>
    

    换行的时候可以直接用回车

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var myname = "yangze";
    var getName = function () {
    return "yangze";
    };
    console.log(`hello ${myname}`);
    console.log(`hello ${getName()}`);
    //拼接字符串不需要+''+
    console.log(`<div>
    <span>${myname}</span>
    <span>${getName()}</span>
    </div>`);
  • 自动拆分字符串

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function test(template,name,age){
    console.log(template);
    console.log(name);
    console.log(age);
    }
    var myname = "yangze";
    var getAge = function () {
    return 28;
    };
    test`hello my name is ${myname}, i'm ${getAge()} `;
    //返回结果
    Array[3]
    yangze
    28

参数类型

  • 参数后面可以使用:来指定参数的类型

    var myname: string = "yangze";

    var alias:any = 'xixi';

    var age:number=12;

    var man: boolean = true;

    function test():void{//}如果使用void ,函数内不可以return

    1
    2
    3
    4
    function test(name:string):string{
    return 'string'
    }
    test('hello');
  • 自定义类型

    1
    2
    3
    4
    5
    6
    //自定义类型
    class Person{
    name: string;
    age: number;
    }
    var zhangsan: Person = new Person();

参数默认值

1
2
3
4
5
6
7
var myname: string = "yangze";
function test(a:string,b:string,c:string){
console.log(a);
console.log(b);
console.log(c);
}
test("xxx", "yyy", "zzz");//如果参数不够会报错
1
2
3
4
5
6
7
// var myname: string = "yangze";
function test(a:string,b:string,c:string="jojo"){
console.log(a);
console.log(b);
console.log(c);
}
test("xxx", "yyy");//此时可以传两个参数,第三个参数取默认值jojo

注意:带默认值得参数声明在最后面

1
2
3
4
5
6
function test(a:string,b?:string,c:string="jojo"){
console.log(a);
console.log(b);
console.log(c);
}
test("xxx");//返回 xxx,undefined,jojo

注意:问号不可以放在第一个参数

TypeScript-Rest and Spread ...

用来声明任意数量的方法和参数

  • 参数任意

    1
    2
    3
    4
    5
    6
    7
    function func1(...args){
    args.forEach(function (arg) {
    console.log(arg);
    })
    }
    func1(1, 2, 3);
    func1(7, 8, 9, 10, 11);
  • 参数固定

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function func1(a,b,c){
    console.log(a);
    console.log(b);
    console.log(c);
    }
    var args1 = [1, 2];
    func1(...args1);
    var args2 = [7, 8, 9, 10, 11];
    func1(...args2);
    /**
    * 1
    * 2
    * undefined
    * 7
    * 8
    * 9
    * */

TypeScript-generator函数

1
2
3
4
5
6
7
8
function* doSomething(){
console.log("start");
yield;
console.log("finish");
}
var func1 = doSomething();
func1.next();//执行到yield停止,打印start
func1.next();//finish

demo

1
2
3
4
5
6
7
8
9
10
11
12
13
function* getStockPrice(stock){
while(true){
yield Math.random()*100;
}
}
var priceGenerator=getStockPrice("IBM");
var limitPrice=15;
var price=100;
while(price>limitPrice){
price=priceGenerator.next().value;
console.log(`the generator return ${price}`);
}
console.log(`buying at ${price}`)

TypeScript-destructuring析构表达式

通过表达式将对象或数组拆解成任意数量的变量

在es5中:

1
2
3
4
5
6
7
8
9
function getStock(){
return {
code: "IBM",
price: 100
};
}
var stock = getStock();
var code = stock.code;
var price = stock.price;

在TypeScript中

1
2
3
4
5
6
7
function getStock(){
return {
code: "IBM",
price: 100
};
}
var {code , price} = getStock();

注意:名字要一致,也可以给对象属性起一个别名

var {code:codex , price} = getStock();

访问对象中的对象:

1
2
3
4
5
6
7
8
9
10
function getStock(){
return {
code: "IBM",
price: {
price1: 100,
price2:200
}
};
}
var {code , price:{price1}} = getStock();

以上为针对对象的析构表达式,一下是针对数组的析构表达式:

1
2
3
4
5
var arr = [1, 2, 3, 4];
var [number1, number2] = arr;//1,2
var [ , ,number1, number2] = arr;//3,4
var [number1, , , number2] = arr;//1,4
var [number1 , number2 , ...others] = arr;//1,2,[3,4]

在函数中的调用:

1
2
3
4
5
6
7
var arr = [1, 2, 3, 4];
function doSomething([number1, number2, ...others]) {
console.log(number1);
console.log(number2);
console.log(others);
}
doSomething(arr);

箭头表达式

用来声明匿名函数,消除传统匿名函数的this指针问题

1
2
3
4
5
6
7
8
9
10
//单行写法:
var sum = (arg1, arg2) => arg1 + arg2;
//多行写法:
var sum = (arg1, arg2) => {
return arg1 + arg2
};
//只有一个参数的写法:
var sum = arg => {
console.log(arg)
}

箭头表达式用于匿名函数:

1
2
var arr = [1, 2, 3, 4];
console.log(arr.filter(value => value%2 == 0)); //[2 , 4]

箭头函数消除传统匿名函数this的指针问题:

1
2
3
4
5
6
7
function Stock(name) {
this.name = name;
setInterval(() => {
console.log(this.name);//hehehe
},1000)
}
var a = new Stock('hehehe')

TypeScript-for of循环

1
2
3
var arr = [1, 2, 3, 4, 5];
arr.desc = 'hello';
arr.forEach(value=>console.log(value))

forEach会忽略掉属性desc,并且不能使用break

1
2
3
4
5
var arr = [1, 2, 3, 4, 5];
arr.desc = 'hello';
for (var i in arr) {
console.log(i);
}

for in 遍历属性的名字,包括desc

1
2
3
4
5
6
7
8
9
var arr = [1, 2, 3, 4, 5];
arr.desc = 'hello';
for (var i of arr) {
console.log(i)
}
/***********************/
for (var i of 'hello world') {
console.log(i)
}

for of 会忽略掉desc这个属性,这个循环可以被break打断,还可以将字符串的每个字符打印

TypeScript面向对象特效

TypeScript-类

类是TypeScript的核心,使用TypeScript时,大部分代码都是写在类里面的.

class Person{}声明一个类,可以指定属性,和类的方法

1
2
3
4
5
6
7
8
9
10
11
12
class Person{
private name;
eat() {
console.log("i'm eatting")
}
}
var p1 = new Person();
p1.name = 'batman';
p1.eat();
var p2 = new Person();
p2.name = 'superman';
p2.eat();

属性模式是公共的方法public,可以指定private来指定私有的方法,这样在类的外部无法访问到私有的属性,只能在类的内部访问.也可以指定protected,这样可以在类的内部,和类的子类(继承)中可以访问到,在外部不可以访问.

类的构造函数constructor

在类实例化的时候可以被调用,在外部不可以访问constructor这个方法,只有在实例化new时会被调用.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person{
constructor(){
console.log("haha");//被实例化两次,打印两次haha
}
private name;
eat() {
console.log("i'm eatting")
}
}
var p1 = new Person();
p1.name = 'batman';
p1.eat();
var p2 = new Person();
p2.name = 'superman';
p2.eat();

给constructor传递参数后,实例化的时候必须传参数

1
2
3
4
5
6
7
8
9
10
11
12
13
class Person{
name;
constructor(name:string){
this.name = name;
}
eat() {
console.log(this.name)
}
}
var p1 = new Person('batman');
p1.eat();
var p2 = new Person('superman');
p2.eat();

上面的name,可以简写到constructor里,但是要明确声明访问控制符

1
2
3
4
5
6
7
8
9
10
11
12
class Person{
constructor(public name:string){
this.name = name;
}
eat() {
console.log(this.name)
}
}
var p1 = new Person('batman');
p1.eat();
var p2 = new Person('superman');
p2.eat();

类的继承extendssuper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Person{
constructor(public name:string){
console.log("haha");
}
eat() {
console.log(this.name)
}
}
class Employee extends Person {
code: string;
work() {

}
}
var e1 = new Employee("name");
var p1 = new Person('batman');
p1.eat();
var p2 = new Person('superman');
p2.eat();

super的用法:

  1. 调用父类的构造函数,子类的构造函数必须要调用父类的构造函数(规定)
  2. 调用父类的其他方法
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
class Person{
constructor(public name:string){
console.log("haha");
}
eat() {
console.log("I'm eating")
}
}
class Employee extends Person {
constructor(name: string, code: string) {
super(name);
console.log("xixi");
this.code = code;
}
code: string;
work() {
super.eat();
this.doWork();
}
private doWork() {
console.log("I'm working")
}
}
var e1 = new Employee("name", "12");
e1.work();
//e1.无法调用doWork()

TypeScript-泛型generic

用来限制集合的类型

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
class Person{
constructor(public name:string){
console.log("haha");
}
eat() {
console.log("I'm eating")
}
}
class Employee extends Person {
constructor(name: string, code: string) {
super(name);
console.log("xixi");
this.code = code;
}
code: string;
work() {
super.eat();
this.doWork();
}
private doWork() {
console.log("I'm working")
}
}

var workers: Array<Person> = [];
workers[0] = new Person("zhangsan");
workers[1] = new Employee("lisi", "2");
workers[2] = "12"//报错

var e1 = new Employee("name", "12");

先给workers指定一个类型Array,Person就是数组Array的泛型,数组中只能放Person类型的数据,Employee继承自Person

TypeScript-接口Interface

用来建立代码约定,使得其它开发者在调用摸个方法或创建新的类时必须遵循接口所定义的代码约定

  • 使用interface声明属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    interface IPerson{
    name: string;
    age: number;
    }
    class Person{
    constructor(public config: IPerson) {

    }
    }
    var p1 = new Person({
    name: 'heloo',
    age:18,
    xxx:123//如果多传了属性,报错
    })
  • 使用interface声明方法,然后是用implement实现接口,所有类必须实现接口里的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    interface Animal{
    eat();
    }
    class Sheep implements Animal{
    eat() {
    console.log("I eat grass");
    }
    }
    class Tiger implements Animal{
    eat() {
    console.log("I eat meat");
    }
    }

TypeScript-模块Module

  • 模块可以帮助开发者将代码分割为可重用的单元.开发者可以自己决定模块中的那些资源(类,方法,变量)暴露出去共外部使用,那些资源只在模块内使用.

  • 使用export暴露属性方法和类,使用import引入属性方法和类

  • 每个模块既可以export也可以import
    1
    2
    3
    4
    5
    6
    7
    //模块a:
    export var prop1;
    var prop2;
    export function func1(){}
    function func2(){}
    export class Clazz1(){}
    class Clazz2(){}
1
2
3
4
5
6
//模块b
import {prop1, func1, Clazz1} from "./a";
console.log(prop1);
func1();
new Clazz1{}
export function func3(){}