web前端之TypeScript


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

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

typescript 复制代码
// 使用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(构造函数)

typescript 复制代码
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

typescript 复制代码
// 自执行函数的作用是形成单独模块(块作用域),
// 防止此文件的变量或方法与其他文件的属性或方法冲突
(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

typescript 复制代码
// 自执行函数的作用是形成单独模块(块作用域),
// 防止此文件的变量或方法与其他文件的属性或方法冲突
(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

typescript 复制代码
// 自执行函数的作用是形成单独模块(块作用域),
// 防止此文件的变量或方法与其他文件的属性或方法冲突
(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

typescript 复制代码
enum Gender {
    Male,
    Female
};

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

console.log(i.gender === Gender.Male); // true
相关推荐
我要洋人死43 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風6 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#