Sök…


Introduktion

TypeScript, som ECMA Script 6, stöder objektorienterad programmering med klasser. Detta står i kontrast till äldre JavaScript-versioner, som endast stödde prototypbaserad arvskedja.

Klassstödet i TypeScript liknar det för språk som Java och C #, eftersom klasser kan ärva från andra klasser, medan objekt instanseras som klassinstanser.

TypScript-klasser kan också likna dessa språk implementera gränssnitt eller använda generiska.

Enkel klass

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

I det här exemplet förklarar vi en enkel Car . Klassen har tre medlemmar: en privat egendom speed , en allmän egendom position och en offentlig metod move . Observera att varje medlem är offentlig som standard. Det är därför move() är offentligt, även om vi inte använde det public nyckelordet.

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

Grundläggande arv

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();
    }
}

Exemplen visar hur man skapar en mycket enkel underklass i Car hjälp av extends nyckelordet. SelfDrivingCar åsidosätter metoden för att move() och använder implementeringen av basklassen med super .

konstruktörer

I det här exemplet använder vi constructor att förklara en allmän egendom position och en skyddad egendom speed i basklassen. Dessa egenskaper kallas Parameteregenskaper . De låter oss förklara en konstruktörsparameter och en medlem på ett ställe.

En av de bästa sakerna i TypeScript är automatisk tilldelning av konstruktörsparametrar till den relevanta egenskapen.

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

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

All denna kod kan återupptas i en enda konstruktör:

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

Och båda kommer att transporteras från TypeScript (designtid och kompileringstid) till JavaScript med samma resultat, men skriver betydligt mindre kod:

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

Konstruktörer av härledda klasser måste anropa basklasskonstruktören med 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

I det här exemplet modifierar vi exemplet "Enkel klass" för att ge åtkomst till speed . Typskriptåtkomstmöjligheter tillåter oss att lägga till ytterligare kod i brev eller setare.

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

Abstrakta klasser

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!"

Abstrakta klasser är basklasser från vilka andra klasser kan sträcka sig. De kan inte instanseras själva (dvs. du kan inte göra en new Machine("Konda") ).

De två viktiga egenskaperna hos en abstrakt klass i Typescript är:

  1. De kan implementera sina egna metoder.
  2. De kan definiera metoder som ärva klasser måste implementera.

Av denna anledning kan abstrakta klasser konceptuellt betraktas som en kombination av ett gränssnitt och en klass .

Monkey patch en funktion i en befintlig klass

Ibland är det användbart att kunna utöka en klass med nya funktioner. Låt oss till exempel anta att en sträng bör konverteras till en kamelfallsträng. Så vi måste berätta för TypeScript att String innehåller en funktion som heter toCamelCase , som returnerar en string .

interface String {
    toCamelCase(): string;
}

Nu kan vi korrigera denna funktion i String implementeringen.

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']();
        });
}

Om denna förlängning av String laddas kan den användas på följande sätt:

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

Transpilation

Med tanke på en klass SomeClass , låt oss se hur TypeScript transpileras till JavaScript.

TypeScript-källa

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-källa

När de transpileras med TypeScript v2.2.2 är utdata så:

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";

observationer

  • Modifieringen av klassens prototyp är insvept i en IIFE .
  • Medlemsvariabler definieras i huvudklassen function .
  • Statiska egenskaper läggs direkt till klassobjektet, medan instansegenskaper läggs till i prototypen.


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow