Zoeken…


Invoering

TypeScript ondersteunt, net als ECMA Script 6, objectgericht programmeren met behulp van klassen. Dit in tegenstelling tot oudere JavaScript-versies, die alleen op prototypen gebaseerde overervingsketen ondersteunden.

De klassenondersteuning in TypeScript is vergelijkbaar met die van talen zoals Java en C #, omdat klassen kunnen erven van andere klassen, terwijl objecten als klasseninstanties worden geïnstantieerd.

Ook vergelijkbaar met die talen, kunnen TypeScript-klassen interfaces implementeren of gebruikmaken van generieke geneesmiddelen.

Eenvoudige les

class Car {
    public position: number = 0;
    private speed: number = 42;
    
    move() {
        this.position += this.speed;
    }
}    

In dit voorbeeld verklaren we een eenvoudige klasse Car . De klasse bestaat uit drie leden: een prive-eigendom speed , een publiek eigendom position en een openbare methode move . Merk op dat elk lid standaard openbaar is. Daarom is move() openbaar, zelfs als we het public trefwoord niet hebben gebruikt.

var car = new Car();        // create an instance of Car
car.move();                 // call a method
console.log(car.position);  // access a public property

Fundamentele erfenis

class Car {
    public position: number = 0;
    protected speed: number = 42;
    
    move() {
        this.position += this.speed;
    }
}  

class SelfDrivingCar extends Car {

    move() {
        // start moving around :-)
        super.move();
        super.move();
    }
}

Dit voorbeeld laat zien hoe u een zeer eenvoudige subklasse van het creëren Car klasse met behulp van de extends trefwoord. De klasse SelfDrivingCar overschrijft de methode move() en gebruikt de basisklasse-implementatie met super .

constructors

In dit voorbeeld gebruiken we de constructor om een publiek bezit verklaren position en een beschermd pand speed in de basisklasse. Deze eigenschappen worden parameter-eigenschappen genoemd . Ze laten ons een constructorparameter en een lid op één plaats verklaren.

Een van de beste dingen in TypeScript is de automatische toewijzing van constructorparameters aan de relevante eigenschap.

class Car {
    public position: number;        
    protected speed: number;

    constructor(position: number, speed: number) {
        this.position = position;
        this.speed = speed;
    }
    
    move() {
        this.position += this.speed;
    }        
}

Al deze code kan in één enkele constructor worden hervat:

class Car {
    constructor(public position: number, protected speed: number) {}
    
    move() {
        this.position += this.speed;
    }        
}

En beide zullen van TypeScript (ontwerptijd en compilatietijd) worden overgezet naar JavaScript met hetzelfde resultaat, maar met aanzienlijk minder code:

var Car = (function () {
    function Car(position, speed) {
        this.position = position;
        this.speed = speed;
    }
    Car.prototype.move = function () {
        this.position += this.speed;
    };
    return Car;
}());

Constructors van afgeleide klassen moeten de constructor van de basisklasse aanroepen met super() .

class SelfDrivingCar extends Car {
    constructor(startAutoPilot: boolean) {
        super(0, 42);
        if (startAutoPilot) {
            this.move();
        }
    }
}

let car = new SelfDrivingCar(true);
console.log(car.position);  // access the public property position

accessors

In dit voorbeeld wijzigen we het voorbeeld "Simple class" om toegang tot de eigenschap speed . Met typografische accessors kunnen we extra code toevoegen in getters of setters.

class Car {
    public position: number = 0;
    private _speed: number = 42;
    private _MAX_SPEED = 100
    
    move() {
        this.position += this._speed;
    }
    
    get speed(): number {
        return this._speed;
    }

    set speed(value: number) {
        this._speed = Math.min(value, this._MAX_SPEED);
    }
}

let car = new Car();
car.speed = 120;
console.log(car.speed);  // 100

Abstracte klassen

abstract class Machine {
    constructor(public manufacturer: string) {
    }

    // An abstract class can define methods of it's own, or...
    summary(): string {
        return `${this.manufacturer} makes this machine.`;
    }
    
    // Require inheriting classes to implement methods
    abstract moreInfo(): string;
}

class Car extends Machine {
    constructor(manufacturer: string, public position: number, protected speed: number) {
        super(manufacturer);
    }
    
    move() {
        this.position += this.speed;
    }
    
    moreInfo() {
        return `This is a car located at ${this.position} and going ${this.speed}mph!`;
    }
}

let myCar = new Car("Konda", 10, 70);
myCar.move(); // position is now 80
console.log(myCar.summary()); // prints "Konda makes this machine."
console.log(myCar.moreInfo()); // prints "This is a car located at 80 and going 70mph!"

Abstracte klassen zijn basisklassen van waaruit andere klassen kunnen worden uitgebreid. Ze kunnen zelf niet worden geïnstantieerd (u kunt dus geen new Machine("Konda") ).

De twee belangrijkste kenmerken van een abstracte klasse in Typescript zijn:

  1. Ze kunnen eigen methoden implementeren.
  2. Ze kunnen methoden definiëren die klassen moeten overnemen.

Om deze reden kunnen abstracte klassen conceptueel worden beschouwd als een combinatie van een interface en een klasse .

Monkey koppelt een functie aan een bestaande klasse

Soms is het handig om een klasse uit te breiden met nieuwe functies. Laten we bijvoorbeeld veronderstellen dat een string moet worden geconverteerd naar een camel case string. We moeten dus TypeScript vertellen dat die String functie toCamelCase , die een string teruggeeft.

interface String {
    toCamelCase(): string;
}

Nu kunnen we deze functie patchen in de String implementatie.

String.prototype.toCamelCase = function() : string {
    return this.replace(/[^a-z ]/ig, '')
        .replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match: any, index: number) => {
            return +match === 0 ? "" : match[index === 0 ? 'toLowerCase' : 'toUpperCase']();
        });
}

Als deze extensie van String is geladen, kan deze als volgt worden gebruikt:

"This is an example".toCamelCase();    // => "thisIsAnExample"

Transpilation

Gegeven een klasse SomeClass , laten we eens kijken hoe de TypeScript wordt omgezet in JavaScript.

TypeScript-bron

class SomeClass {

    public static SomeStaticValue: string = "hello";
    public someMemberValue: number = 15;
    private somePrivateValue: boolean = false;

    constructor () {
        SomeClass.SomeStaticValue = SomeClass.getGoodbye();
        this.someMemberValue = this.getFortyTwo();
        this.somePrivateValue = this.getTrue();
    }

    public static getGoodbye(): string {
        return "goodbye!";
    }

    public getFortyTwo(): number {
        return 42;
    }

    private getTrue(): boolean {
        return true;
    }

}

JavaScript-bron

Bij transpiling met TypeScript v2.2.2 is de uitvoer als volgt:

var SomeClass = (function () {
    function SomeClass() {
        this.someMemberValue = 15;
        this.somePrivateValue = false;
        SomeClass.SomeStaticValue = SomeClass.getGoodbye();
        this.someMemberValue = this.getFortyTwo();
        this.somePrivateValue = this.getTrue();
    }
    SomeClass.getGoodbye = function () {
        return "goodbye!";
    };
    SomeClass.prototype.getFortyTwo = function () {
        return 42;
    };
    SomeClass.prototype.getTrue = function () {
        return true;
    };
    return SomeClass;
}());
SomeClass.SomeStaticValue = "hello";

Waarnemingen

  • De aanpassing van het prototype van de klasse is verpakt in een IIFE .
  • Lidvariabelen worden binnen de hoofdklasse- function gedefinieerd.
  • Statische eigenschappen worden rechtstreeks aan het klasseobject toegevoegd, terwijl instantie-eigenschappen aan het prototype worden toegevoegd.


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow