TypeScript
Klassen
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:
- Ze kunnen eigen methoden implementeren.
- 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.