根据TypeScript文档,扩展已有的接口就像使用新属性重新声明它一样简单,然后为这些接口提供实现。我已经习惯了这种技术多次向本机JavaScript对象添加静态方法扩展。但是,这对成员函数不起作用。
例如(TypeScript Playground link):
interface Number {
toPowerOf10: () => string;
}
Number.prototype.toPowerOf10 = (): string => {
return this.toExponential();
}
var n: Number = 10000;
n.toPowerOf10();
上面的代码编译得很好,但在运行时会抛出以下异常:
Uncaught TypeError: _this.toExponential is not a function
罪魁祸首似乎是TypeScript为此场景生成JavaScript代码的方式:
var _this = this;
Number.prototype.toPowerOf10 = function () {
return _this.toExponential();
};
var n = 1000;
alert(n.toPowerOf10());
很明显_this
在这里没有引用Number
实例。我不确定我是否做错了,或者在TypeScript中是否支持以这种方式扩展本机对象。
答案 0 :(得分:11)
这是因为您使用箭头符号(=>
)来声明新函数而不是function
。虽然=>
对于同一件事来说似乎是一个很好的速记,但它和function
并不完全相同。特别是,=>
将执行词法作用域,这意味着该函数的this
外部将引用与this
内部相同的内容>该函数,它通过捕获已编译的JavaScript中的本地_this
来完成。在这里,this
是全局范围,因为您在那里声明Number
扩展名。如果这是一个浏览器this
,则会引用window
对象,该对象当然没有toExponential
方法。
要完成您想要的任务,只需使用以下内容:
interface Number {
toPowerOf10: () => string;
}
Number.prototype.toPowerOf10 = function() : string {
return this.toExponential();
}
var n: Number = 10000;
document.write(n.toPowerOf10());