zoukankan      html  css  js  c++  java
  • typescript-学习使用ts-2

    解构赋值

    数组解构

    let input = [1, 2];
    let [first, second] = input;
    console.log(first); // outputs 1
    console.log(second); // outputs 2
    

    上面的写法等价于:

    first = input[0];
    second = input[1];
    

    利用解构赋值交换变量:

    [first, second] = [second, first];
    

    函数参数解构:

    function f ([first, second]: [number, number]) [
      console.log(first)
      console.log(second)
    ]
    
    f(1, 2)
    

    解构剩余参数:

    let [first, ...rest] = [1, 2, 3, 4]
    console.log(first) // 1
    console.log(rest) // [2, 3, 4]
    

    也可以忽略其它参数:

    let [first] = [1, 2, 3, 4];
    console.log(first); // outputs 1
    

    或者跳过解构:

    let [, second, , fourth] = [1, 2, 3, 4]
    

    对象解构

    示例一:

    let o = {
        a: "foo",
        b: 12,
        c: "bar"
    };
    let { a, b } = o;
    

    就像数组解构,你可以用没有声明的赋值:

    let a: number,
      b: number;
    
    ({a, b} = {a: 123, b: 456})
    
    console.log(a, b) // 123 456
    

    你可以在对象里使用 ... 语法创建剩余变量:

    let { a, ...passthrough } = o;
    let total = passthrough.b + passthrough.c.length;
    

    属性解构重命名

    你也可以给属性以不同的名字:

    let { a: newName1, b: newName2 } = o;
    

    注意,这里的冒号不是指示类型的。 如果你想指定它的类型, 仍然需要在其后写上完整的模式。

    let {a, b}: {a: string, b: number} = o;
    

    默认值

    function keepWholeObject(wholeObject: { a: string, b?: number }) {
        let { a, b = 1001 } = wholeObject;
    }
    

    展开操作符

    • 展开数组
    • 展开对象
      • 不会展开方法

    解构赋值用于函数声明

    type C = {a: string, b?: number}
    
    function f ({a, b}: C): void {
      // ...
    }
    

    解构赋值用于加载指定模块成员

    基本示例

    class Person {
        name: string;
        age: number;
    
        constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
        }
    
        sayHello() {
            console.log(this.name);
        }
    }
    
    let zs: Person = new Person('张三', 18);
    
    

    构造函数

    继承

    class Animal {
        move(distanceInMeters: number = 0) {
            console.log(`Animal moved ${distanceInMeters}m.`);
        }
    }
    
    class Dog extends Animal {
        bark() {
            console.log('Woof! Woof!');
        }
    }
    
    const dog = new Dog();
    dog.bark();
    dog.move(10);
    dog.bark();
    

    这个例子展示了最基本的继承:类从基类中继承了属性和方法。 这里, Dog是一个 派生类,它派生自 Animal 基类,通过 extends关键字。 派生类通常被称作 子类,基类通常被称作 超类

    因为 Dog继承了 Animal的功能,因此我们可以创建一个 Dog的实例,它能够 bark()move()

    下面是一个更复杂的例子:

    class Animal {
        name: string;
        constructor(theName: string) { this.name = theName; }
        move(distanceInMeters: number = 0) {
            console.log(`${this.name} moved ${distanceInMeters}m.`);
        }
    }
    
    class Snake extends Animal {
        constructor(name: string) { super(name); }
        move(distanceInMeters = 5) {
            console.log("Slithering...");
            super.move(distanceInMeters);
        }
    }
    
    class Horse extends Animal {
        constructor(name: string) { super(name); }
        move(distanceInMeters = 45) {
            console.log("Galloping...");
            super.move(distanceInMeters);
        }
    }
    
    let sam = new Snake("Sammy the Python");
    let tom: Animal = new Horse("Tommy the Palomino");
    
    sam.move();
    tom.move(34);
    

    与前一个例子的不同点是,派生类包含了一个构造函数,它 必须调用 super(),它会执行基类的构造函数。 而且,在构造函数里访问 this的属性之前,我们 一定要调用 super()。 这个是TypeScript强制执行的一条重要规则。

    这个例子演示了如何在子类里可以重写父类的方法。 Snake类和 Horse类都创建了 move方法,它们重写了从Animal继承来的 move方法,使得 move方法根据不同的类而具有不同的功能。 注意,即使 tom被声明为Animal类型,但因为它的值是 Horse,调用 tom.move(34)时,它会调用 Horse里重写的方法:

    Slithering...
    Sammy the Python moved 5m.
    Galloping...
    Tommy the Palomino moved 34m.
    

    实例成员访问修饰符

    public 开放的

    • 默认为 public
    class Animal {
        public name: string;
        public constructor(theName: string) { this.name = theName; }
        public move(distanceInMeters: number) {
            console.log(`${this.name} moved ${distanceInMeters}m.`);
        }
    }
    

    private 私有的

    • 不能被外部访问,只能在类的内部访问使用
    • 私有成员不会被继承
    class Person {
      public name: string;
      public age: number = 18;
      private type: string = 'human'
      public constructor (name, age) {
        this.name = name
        this.age = age
      }
    }
    

    protected 受保护的

    • private 类似,但是可以被继承
    class Person {
        protected name: string;
        constructor(name: string) { this.name = name; }
    }
    
    class Employee extends Person {
        private department: string;
    
        constructor(name: string, department: string) {
            super(name)
            this.department = department;
        }
    
        public getElevatorPitch() {
            return `Hello, my name is ${this.name} and I work in ${this.department}.`;
        }
    }
    
    let howard = new Employee("Howard", "Sales");
    console.log(howard.getElevatorPitch());
    console.log(howard.name); // 错误
    

    注意,我们不能在 Person类外使用 name,但是我们仍然可以通过 Employee类的实例方法访问,因为Employee是由 Person派生而来的。

    readonly 只读的

    在参数中使用修饰符

    在上面的例子中,我们不得不定义一个受保护的成员 name和一个构造函数参数 theNamePerson类里,并且立刻给 nametheName赋值。 这种情况经常会遇到。 参数属性可以方便地让我们在一个地方定义并初始化一个成员。

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

    可以简写为:

    class Person {
        constructor(public name: string, public age: number) {
        }
    }
    

    属性的存(get)取(set)器

    let passcode = "secret passcode";
    
    class Employee {
      	// 私有成员,外部无法访问
        private _fullName: string;
    
      	// 当访问 实例.fullName 的时候会调用 get 方法
        get fullName(): string {
            return this._fullName;
        }
    
      	// 当对 实例.fullName = xxx 赋值的时候会调用 set 方法
        set fullName(newName: string) {
            if (passcode && passcode == "secret passcode") {
                this._fullName = newName;
            }
            else {
                console.log("Error: Unauthorized update of employee!");
            }
        }
    }
    
    let employee = new Employee();
    employee.fullName = "Bob Smith";
    if (employee.fullName) {
        alert(employee.fullName);
    }
    

    静态成员

    • 不需要实例化访问的成员称之为静态成员,即只能被类访问的成员
    • static 关键字
    class Grid {
        static origin = {x: 0, y: 0};
        calculateDistanceFromOrigin(point: {x: number; y: number;}) {
            let xDist = (point.x - Grid.origin.x);
            let yDist = (point.y - Grid.origin.y);
            return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
        }
        constructor (public scale: number) { }
    }
    
    let grid1 = new Grid(1.0);  // 1x scale
    let grid2 = new Grid(5.0);  // 5x scale
    
    console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
    console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
    
  • 相关阅读:
    Linux常用命令
    cookie机制、session机制
    http状态码、错误分析
    安装“Microsoft SQL Server 2014 Management Objects”时报错"Error Writing to file: Microsoft.SqlServer.XEvent.Linq.dll."
    Installshield build all installer in development computer
    C++使用RabbitMQ类库做客户端与RabbitMQ Server通讯,生成C++可调用的rabbimq.*.dll的过程
    由hibernate配置cascade而导致的软件错误,并分析解决此问题的过程
    由hibernate配置inverse="true"而导致的软件错误,并分析解决此问题的过程
    JVM原理解析
    Add lombok to IntelliJ IDEA
  • 原文地址:https://www.cnblogs.com/ygjzs/p/12215471.html
Copyright © 2011-2022 走看看