Utvid den innebygde JavaScript Number-objektet i TypeScript
Ifølge TypeScript-dokumentasjonen er det å utvide et allerede eksisterende grensesnitt like enkelt som å erklære det på nytt med nye egenskaper, og deretter gi implementasjon for disse. Jeg har brukt denne teknikken for å legge til statiske metodeutvidelser til native JavaScript-objekter en rekke ganger. Dette fungerer imidlertid ikke for medlemsfunksjoner.
For eksempel (TypeScript Playground-lenke):
interface Number {
toPowerOf10: () => string;
}
Number.prototype.toPowerOf10 = (): string => {
return this.toExponential();
}
var n: Number = 10000;
n.toPowerOf10();
Koden ovenfor kompilerer fint, men under kjøring kaster den følgende unntak:
Uncaught TypeError: _this.toExponential is not a functionSyndefugl ser ut til å være hvordan TypeScript genererer JavaScript-koden for dette scenariet:
var _this = this;
Number.prototype.toPowerOf10 = function () {
return _this.toExponential();
};
var n = 1000;
alert(n.toPowerOf10());
Det er åpenbart at _this ikke har referanse til Number-instansen her. Jeg er ikke sikker på om jeg gjør noe feil, eller om det å utvide native objekter på denne måten ikke støttes i TypeScript.
Svar #1
Det er fordi du bruker pilnotasjonen (=>) for å erklære den nye funksjonen og ikke function. Selv om => kan virke som en fin snarvei for det samme, er den og function ikke helt ekvivalente. Spesielt vil => bruke leksikalsk skop, noe som betyr at this utenfor den funksjonen vil referere til det samme som this innenfor den funksjonen, som det oppnår ved å fange den lokale _this i den kompilerte JavaScripten. Her er this globalt skop, siden du erklærer Number-utvidelsen der. Hvis dette er i en nettleser, vil this referere til window-objektet, som selvfølgelig ikke har noen toExponential-metode.
For å oppnå det du ønsker, bruk ganske enkelt følgende:
declare global {
interface Number {
toPowerOf10: () => string;
}
}
Number.prototype.toPowerOf10 = function() : string {
return this.toExponential();
}
var n: Number = 10000;
document.write(n.toPowerOf10());
