web前端之TypeScript

MENU

  • typescript类型别名、限制值的大小
  • typescript使用class关键字定义一个类、static、readonly
  • typescript中class的constructor(构造函数)
  • typescript中abstractClass(抽象类)、extends、abstract
  • typescript中的接口、type、interface
  • typescript封装属性、public、private、protected、constructor、get、set、extends
  • typescript枚举、enum


typescript类型别名、限制值的大小

type myType = 1 | 2 | 3 | 4 | 5;
let k: myType;
let l: myType;
let m: myType;

k = 2; // 正常
l = 6; // 报错
m = 3; // 正常

typescript使用class关键字定义一个类、static、readonly

// 使用class关键字来定义一个类
// 类对象中主要包含了两个部分:属性和方法
class Person {
	// 01----------------------------------
    // 直接定义的属性是实例属性,需要通过对象的实例去访问
    a = 'a';

    // 02----------------------------------
    // 使用static开头的属性是静态属性(类属性),可以直接通过类去访问
    static b: number = 18;

    // 03----------------------------------
    // readonly开头的属性表示一个只读的属性无法修改
    readonly c: string = '半晨';

    // 04----------------------------------
    // 静态只读属性
    static readonly d: string = '舒冬';

    // 05----------------------------------
    // 直接定义方法
    e() {
        console.log('直接定义方法');
        // 直接定义方法
    }

    // 05----------------------------------
    // 定义静态方法
    static f() {
        console.log('定义静态方法');
        // 定义静态方法
    }
}

const person = new Person();

console.log('Person实例:', person);
// Person实例: Person {a: "a", c: "半晨"}

// 01------------------------------------------------
// 直接定义的属性是实例属性,需要通过对象的实例去访问
console.log('实例属性:', person.a);
// 实例属性: a
// console.log('实例属性:', Person.a);
// 实例属性: undefined 
// 类型“typeof Person”上不存在属性“a”。

// 02------------------------------------------------
// 类属性(静态属性)
console.log('类属性(静态属性):', Person.b);
// 类属性(静态属性): 18
// console.log('类属性(静态属性):', person.b);
// 类属性(静态属性): undefined
// 属性“b”在类型“Person”上不存在。你的意思是改为访问静态成员“Person.b”吗?

// 03------------------------------------------------
// readonly开头的属性表示一个只读的属性无法修改
console.log('只读属性:', person.c);
// 只读属性: 半晨
// person.c = '哈哈';
// 无法分配到 "c" ,因为它是只读属性。

// 04------------------------------------------------
// 静态只读属性
console.log('静态只读属性:', Person.d);
// 静态只读属性: 舒冬
// Person.d = '哈哈';
// 无法分配到 "d" ,因为它是只读属性。

// 05------------------------------------------------
// 直接定义方法
person.e();
// Person.e();
// 类型“typeof Person”上不存在属性“e”。

// 05------------------------------------------------
// 直接定义方法
Person.f();
// person.f();
// 属性“f”在类型“Person”上不存在。你的意思是改为访问静态成员“Person.f”吗?

typescript中class的constructor(构造函数)

class Dog {
    // 01--------------------------------------------------------
    // name = '旺财';
    // age = 7;

    // 02--------------------------------------------------------
    // name: string;
    // 属性“name”没有初始化表达式,且未在构造函数中明确赋值。
    // age: number;
    // 属性“age”没有初始化表达式,且未在构造函数中明确赋值。

    // 构造函数会在对象创建时执行
    constructor(name: string, age: number) {
        // 在实例方法中,this就表示当前当前的实例
        // 在构造函数中当前对象就是当前新建的那个对象
        // 可以通过this向新建的对象中添加属性
        this.name = name;
        this.age = age;
    }

    bark() {
        console.log('汪汪汪');
        // 汪汪汪

        // 在方法中可以通过this来表示当前调用方法的对象
        return this.name;
    }
}

// 错误示例--------------------------------------------------------
// const dog1 = new Dog();
// const dog2 = new Dog();

// 01--------------------------------------------------------
// console.log('dog1:', dog1);
// // dog1: Dog {name: "旺财", age: 7}
// console.log('dog2:', dog2);
// // dog2: Dog {name: "旺财", age: 7}

// 02--------------------------------------------------------
// console.log('dog1:', dog1);
// // dog1: Dog {}
// console.log('dog2:', dog2);
// // dog2: Dog {}

// 正确示例--------------------------------------------------------
const dog1 = new Dog('小黑', 6);
const dog2 = new Dog('小白', 7);

console.log('dog1:', dog1);
// dog1: Dog {name: "小黑", age: 6}
console.log('dog2:', dog2);
// dog2: Dog {name: "小白", age: 7}

// 03--------------------------------------------------------
// 调用类中的方法
console.log('dog1:', dog1.bark());
// dog1: 小黑
console.log('dog2:', dog2.bark());
// dog1: 小白

typescript中abstractClass(抽象类)、extends、abstract

// 自执行函数的作用是形成单独模块(块作用域),
// 防止此文件的变量或方法与其他文件的属性或方法冲突
(function () {
    // 以abstract开头的类是抽象类,
    // 抽象类和其他类区别不大,只是不能用来创建对象,
    // 也就是不能new Animal()的意思。
    // 抽象类就是专门用来被继承的类
    // 抽象类中可以添加抽象方法

    abstract class Animal {
        name: string;

        constructor(name: string) {
            this.name = name;
        }

        // 定义一个抽象方法
        // 抽象方法使用abstract开头,没有方法体
        // 抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
        // void没有返回值(返回值为空)
        abstract sayHello(): void;
    }

    class Dog extends Animal {
        sayHello() {
            console.log('汪汪汪汪!');
        }
    }

    // 非抽象类“Cat”不会实现继承自“Animal”类的抽象成员“sayHello”。
    class Cat extends Animal {
        // sayHello() {
        //     console.log('喵喵喵喵!');
        // }
    }

    const dog = new Dog('旺财');
    const cat = new Cat('喵喵');

    dog.sayHello();
    cat.sayHello();
})();

typescript中的接口、type、interface

// 自执行函数的作用是形成单独模块(块作用域),
// 防止此文件的变量或方法与其他文件的属性或方法冲突
(function () {
    // 描述一个对象的类型
    type myType = {
        name: string,
        age: number
    };
    const obj: myType = {
        name: 'sss',
        age: 111,
    };
    console.log('myType:', obj);
    // myType: {name: "sss", age: 111}

    // 接口用来定义一个类结构
    // 用来定义一个类中应该包含哪些属性和方法
    // 同时接口也可以当成类型声明去使用
    // 接口可以声明相同的接口名称
    // 只是接口会打散合并
    interface myInterface {
        name: string;
        age: number;
    }

    interface myInterface {
        gender: string;
    }

    // 如果属性个数对应不上会报错
    // 说明了接口是可以定义相同接口名称
    // 并且接口会打散合并
    const objs: myInterface = {
        name: 'sss',
        age: 111,
        gender: '男'
    };
    console.log('myInterface:', objs);
    // myInterface: {name: "sss", age: 111, gender: "男"}

    // 接口可以在定义类的时候去限制类的结构
    // 接口中的所有的属性都不能有实际的值
    // 接口只定义对象的结构,而不考虑实际值
    // 在接口中所有的方法都是抽象方法
    interface myInter {
        name: string;

        sayHello(): void;
    }

    // 定义类时,可以使类去实现一个接口
    // 实现接口就是使类满足接口的要求
    class MyClass implements myInter {
        name: string;

        constructor(name: string) {
            this.name = name;
        }

        sayHello() {
            console.log('大家好~~');
            // 大家好~~
            console.log(this.name);
            // 半晨
        }
    }
    let myclass = new MyClass('半晨');
    myclass.sayHello();
})();

typescript封装属性、public、private、protected、constructor、get、set、extends

// 自执行函数的作用是形成单独模块(块作用域),
// 防止此文件的变量或方法与其他文件的属性或方法冲突
(function () {
    // 可以任意修改类中属性的值
    class ArbitrarilyEdit {
        name: string;
        age: number;

        constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
        }
    }

    let arbitrarilyEdit = new ArbitrarilyEdit('半晨', 24);

    // 在对象中直接设置属性
    // 属性可以任意的被修改
    // 属性可以任意被修改将会导致对象中的数据变得非常不安全
    console.log('before-arbitrarilyEdit:', arbitrarilyEdit);
    // before-arbitrarilyEdit: ArbitrarilyEdit {name: "半晨", age: 24}
    arbitrarilyEdit.name = '舒冬';
    arbitrarilyEdit.age = -33;
    console.log('after-arbitrarilyEdit:', arbitrarilyEdit);
    // arbitrarilyEdit: ArbitrarilyEdit {name: "舒冬", age: -33}

    // 定义一个不可以任意修改类中值的类
    class Person {
        // typescript可以在属性前添加属性的修饰符
        // public 修饰的属性可以在任意位置访问(修改) 默认值
        // private 私有属性,私有属性只能在类内部进行访问(修改)
        // 通过在类中添加方法使得私有属性可以被外部访问
        // protected 受包含的属性,只能在当前类和当前类的子类中访问(修改)
        private _name: string;
        private _age: number;

        constructor(name: string, age: number) {
            this._name = name;
            this._age = age;
        }

        // getter方法用来读取属性
        // setter方法用来设置属性
        // 它们被称为属性的存取器

        // 定义方法,用来获取name属性
        getName() {
            return this._name;
        }

        // 定义方法,用来设置name属性
        setName(value: string) {
            this._name = value;
        }

        getAge() {
            return this._age;
        }

        setAge(value: number) {
            // 判断年龄是否合法
            if (value >= 0) {
                this._age = value;
            }
        }

        get name() {
            return this._name;
        }

        set name(value) {
            this._name = value;
        }

        get age() {
            return this._age;
        }

        set age(value) {
            if (value >= 0) {
                this._age = value
            }
        }
    }

    const per = new Person('半晨', 18);

    console.log('before-per:', per);
    // before-per: Person {_name: "半晨", _age: 18}
    per._name = '舒冬';
    per._age = -36;
    console.log('after-per:', per);
    // after-per: Person {_name: "舒冬", _age: -36}
    // 此时是可以编译通过
    // 但是_name和_age会出现下波浪线提示错误

    // 定义方法,获取name属性
    console.log('getName:', per.getName());
    // getName: 舒冬
    // 定义方法,设置name属性
    per.setName('苏檀');
    console.log('setName:', per.getName());
    // setName: 苏檀

    // 定义方法,获取age属性
    console.log('getAge:', per.getAge());
    // getAge: -36
    // 定义方法,设置age属性
    // 此处无法修改原先赋值为 -36 的值
    per.setAge(-16);
    console.log('setAge:', per.getAge());
    // setAge: -36

    // 使用自带的get和set方法
    console.log('before-getName:', per.name);
    // before-getName: 苏檀
    console.log('before-age:', per.age);
    // before-age: -36
    per.name = '宁毅';
    per.age = 36;
    console.log('after-getName:', per.name);
    // after-getName: 宁毅
    console.log('after-age:', per.age);
    // after-age: 36

    // ----------------------------------------------------------
    class A {
        // protected 受包含的属性,只能在当前类和当前类的子类中访问(修改)
        protected num: number;

        constructor(num: number) {
            this.num = num;
        }
    }

    class B extends A {
        test() {
            console.log(this.num);
            // 33
        }
    }

    const b = new B(3436);
    console.log('before-b:', b);
    // before-b: B {num: 3436}
    b.num = 33;
    // 属性“num”受保护,只能在类“A”及其子类中访问。
    console.log('after-b:', b);
    // after-b: B {num: 33}
    // 本来是不应该修改的,
    // 但是编译时没有限制报错不能生成文件导致结果是可以修改
    b.test();

    // ----------------------------------------------------------
    // 方式一和方式二是一样的效果
    // class C {
    //     name: string;
    //     age: number

    //     // 可以直接将属性定义在构造函数中
    //     constructor(name: string, age: number) {
    //         this.name = name;
    //         this.age = age;
    //     }
    // }

    // 方式二和方式一是一样的效果
    class C {
        // 可以直接将属性定义在构造函数中
        constructor(public name: string, public age: number) {
            console.log(name, age);
            // xxx 111
        }
    }

    const c = new C('xxx', 111);
    console.log('c:', c);
    // c: C {name: "xxx", age: 111}
})();

typescript枚举、enum

enum Gender {
    Male,
    Female
};

let i: { name: string, gender: Gender };
i = { 
	name: '孙悟空', 
	gender: Gender.Male // 'male'
};

console.log(i.gender === Gender.Male); // true

你可能感兴趣的:(TypeScript,web前端,typescript,前端,web)