TypeScript学习笔记(中)

  • TypeScript中类的访问类型
    (1)一个简单的类

    class Person {
    	name: string;
    }
    const person = new Person();
    person.name = "张三";
    console.log(person.name);
    

    (2)public访问属性讲解
    如果对一个属性不加限制,那么这个属性默认就是public
    上面的代码相当于:

    class Person {
    	public name: string;
    }
    

    public意思是允许在类的内部和外部调用。
    比如我们在类内部调用sayHello

    class Person {
    	public name: string;
    	public sayHello() {
    		console.log(this.name + 'say hello');
    	}
    }
    

    这里的sayHello中的this.name就是类的内部调用。
    在类的外部调用:

    class Person {
    	public name: string;
    	public sayHello() {
    		console.log(this.name + 'say hello');
    	}
    }
    const person = new Person();
    person.name = '张三';
    person.sayHello();
    

    (3)private访问属性

    class Person {
    	private name: string;
    	public sayHello(){
    		console.log(this.name + 'say hello');
    	}
    }
    const p = new Person();
    p.name = '张三';//访问私有属性会报错
    p.sayHello();
    

    (4)protected访问属性
    protected允许在类内部集齐子类中使用。

    class Person {
    	protected name: string;
    	public sayHello() {
    		console.log(this.name + 'say hello');
    	}
    }
    class Teacher extends Person {
    	public sayHi() {
    		console.log(this.name);
    	}
    }
    
  • TypeScript类的构造函数
    构造函数就是在类被初始化的时候,自动执行的一个方法。

    (1)类的构造函数

    class Person {
    	public name: string;
    	constructor(name: string) {
    		this.name = name;
    	}
    	//简写 相当于定义了一个name,然后再构造函数里进行了赋值
    	//constructor(public name: string){
    	//}
    }
    const person = new Person('张三');
    console.log(person.name);
    

    (2)类继承中的构造器写法

    class Person {
    	constructor(public name: string)
    }
    class Teacher extends Person {
    	constructor(public age: number) {
    		super('张三');
    	}
    }
    const teacher = new Teacher(18);
    console.log(teacher.age);
    console.log(teacher.name);
    

    这就是子类继承父类并有构造函数的规则,就是在子类里写构造函数时,必须用super调用父类的构造函数。就算父类没有自定义构造函数,子类也要使用super()来调用,否则会报错。

  • TypeScript类的GetterSetterstatic的使用
    访问类型中的private属性可以通过SetterGetter来修改和访问,实现对象的封装。
    (1)类的GetterSetter

    getter属性的关键字是get,后面跟着类似方法的东西,但是它并不是方法,归根到底还是属性。

    class Person {
    	constructor(private _age: number){
    	}
    	get age() {
    		return this._age;
    	}
    	set age(age: number) {
    		this._age = age;
    	}
    }
    const p = new Person(18);
    console.log(p.age);
    p.age = 20;
    console.log(p.age);
    

    (2)类中的static
    static声明的属性和方法,不需要进行声明对象就可以直接使用:

    class Girl {
    	static sayHi() {
    		return "hi world";
    	}
    }
    console.log(Girl.sayHi());
    
  • 类的只读属性和抽象类

    (1)readonly属性

    class Person {
    	readonly _name: string;
    	constructor(name: string) {
    		this._name = name;
    	}
    }
    const person = new Person('张三');
    //person._name = '李四';//由于_name是readonly属性,所以不能在外部修改
    console.log(person._name);
    

    (2)抽象类的使用
    抽象类的关键词是abstract

    abstract class Person {
    	abstract skill() //因为没有具体方法,所以我们不写括号
    }
    

    有了这个抽象类,三个类就可以继承这个类,然后会要求不需实现skill()方法:

    class Waiter extends Girl {
    	skill() {
    		console.log('倒水');
    	}
    }
    class BaseTeacher extends Girl {
    	skill() {
    		console.log('按摩');
    	}
    }
    class SeniorTeacher extends Girl {
    	skill() {
    		console.log('SPA');
    	}
    }
    
  • 联合类型展示
    所谓联合类型,可以认为一个变量可能有两种或两种以上的类型。

    interface Waiter {
    	say: () => {}
    }
    interface Teacher {
    	skill: () => {}
    }
    function selectWho(person: Waiter | Teacher) {
    	person.say()}
    

    但是这时候问题来了,如果直接写一个这样的方法,就会报错,因为selectWho不能准确判断联合类型的实例到底是什么
    这时候引出一个概念叫类型保护
    ①类型断言

    function selectWho(person: Waiter | Teacher) {
    	if(person as Teacker) {
    		person.skill();
    	} else {
    		(person as Waiter).say();
    	}
    }
    

    in语法

    function selectWho(person: Waiter | Teacher) {
    	if("skill" in animal) {
    		person.skill();
    	} else {
    		person.say();
    	}
    }
    

    typeof语法

    function add(first: string | number, second: string | number) {
    	return first + second;
    }
    
    function add(first: string | number, second: string | number) {
      if (typeof first === "string" || typeof second === "string") {
    	return `${first}${second}`;
    }
    return first + second;
    }
    

    instanceof语法
    保护的是一个对象,可以用instanceof

    class NumberObj {
    	count: number;
    }
    function addObj(first: object | NumberObj, second: object | NumberObj) {
    	if(first instanceof NumberObj && second instanceof NumberObj) {
    		return first.count + second.count;
    	}
    	return 0;
    }
    
  • Enum枚举类型讲解

    enum Status {
    	MASSAGE, //0
    	SPA, //1
    	DBJ //2
    }
    function getServe(status: any) {
    	if(status === Status.MASSAGE) {
    		return "message";
    	} else if(status === Status.SPA) {
    		return 'spa'
    	}
    }
    

    枚举值默认是从0开始的。

  • 泛型
    泛型的定义使用<>(尖括号)进行定义

    (1)TypeScript函数泛型

    function join<T>(first: T, second: T) {
    	return `${first}${second}`;
    }
    join<string>("a","b")
    //如果是number类型
    join<number>(1, 2);
    

    (2)泛型中数组的使用

    function fun<T>(params: T[]) {
    	return params;
    }
    fun <string>["123", "456"]
    //第二种写法
    function fun<T>(params: Array<T>) {
    	return params;
    }
    fun< string > ['123', '456'];
    

    (3)多个泛型的定义

    function join<T, P>(first: T, second: P) {
    	return `${first}${second}`;
    }
    join<number, string> (1, "2");
    

    (4)泛型的类型推断

    function join<T, P> (first: T, second: P) {
    	return `${first}${second}`;
    }
    join(1, "2");
    

    (5)类的泛型

    class SelectPerson<T> {
    	constuctor(private person: T[]) {};
    	getPerson(index: number): T {
    		return this.person[index];
    	}
    }
    const selectPerson = new SelectPerson <string> (['张三', '李四', '王五']);
    console.log(selectPerson.getPerson(1));
    

    (6)泛型中的继承

    interface Person{
    	name: string;
    }
    class SelectGirl<T extends Person> {
    	constructor(private people: T[]){};
    	getPerson(index: number): string {
    		return this.people[index].name
    	}
    }
    const selectGirl = new SelectGirl([
    	{name: '张三'},
    	{name: '李四'},
    	{name: '王五'}
    ])
    console.log(selectGirl.getPerson(1));
    

    (7)泛型约束
    泛型可以使任意类型,可以是对象、字符串、布尔、数字都是可以的。
    但是现在要求泛型必须是string或者number类型。

    class SelectGirl<T> {
    	constructor(private girls: Array<T>) {};
    	getGirl(index: number): T {
    		return this.girls[index];
    	}
    }
    const selectGirl = new SelectGirl<string>(['张三', '李四']);
    console.log(selectGirl.getGirl(1));
    
    class SelectGirl<T extends number | string> {//可以限制只输入nuber或者string
    	
    }
    
  • 命名空间-Namespace
    命名空间这个语法,很类似编程中的模块化思想,比如webpack打包的时候每个模块有自己的环境,不会污染其他模块,不会产生全局变量。命名空间跟这个很类似。
    命名空间的关键字是namespace,需要暴露出去的类可以使用export关键词,这个只有暴露出去的类时全局的,其他的就不会再全局污染了:

    namespace Home {
    	class Header {
    		constructor() {
      			const elem = document.createElement("div");
          		elem.innerText = "This is Header";
    	  		document.body.appendChild(elem);
    		}
    	}
    
    	class Content {
    		constructor() {
    	    const elem = document.createElement("div");
    	    elem.innerText = "This is Content";
    	    document.body.appendChild(elem);
    	  }
    	}
    
    	class Footer {
    		constructor() {
    	    const elem = document.createElement("div");
    	    elem.innerText = "This is Footer";
    	    document.body.appendChild(elem);
    	  }
    	}
    
    	export class Page {
    		constructor() {
    			constructor() {
    				new Header();
    				new Content();
    				new Footer();
    			}
    		}
    	}
    }
    
    new Home.Page();
    
    

    (1)子命名空间

    namespace Components {
    	export namespace SubComponents{
    		export class Test {};
    	}
    }
    

    个人理解:命名空间中只有export的内容在外部才能访问

  • TypeScript如何使用import语法

    //components.ts
    export class Header {
    	constructor() {
    		const elem = document.createElement("div");
    		document.body.appendChild(elem);
    	}
    }
    //引入
    import { Header } from "./components"
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值