尝试this link,其中包括以下TS类,该类扩展了另一个类:
class ExtArray<T> extends Array<T> {
log() {
console.log(this)
}
}
var a = new ExtArray(1,2,3)
a.log()
a.log
应该确实存在,而且TS能够对其进行编译。但是,JS输出无法调用ExtArray.prototype.log:
VM107:22 Uncaught TypeError: a.log is not a function
at <anonymous>:22:3
输出:
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var ExtArray = /** @class */ (function (_super) {
__extends(ExtArray, _super);
function ExtArray() {
return _super !== null && _super.apply(this, arguments) || this;
}
ExtArray.prototype.log = function () {
console.log(this);
};
return ExtArray;
}(Array));
var a = new ExtArray(1, 2, 3);
a.log();
怎么了?
答案 0 :(得分:1)
首先,我强烈认为您已找到一个错误-请向打字稿问题报告该错误。(请参阅jcalz的评论)。
关于造成这种情况的原因,有技术上的解释。
Array
函数在各种方式上都是“特殊的”,其中之一是,无论您直接调用它还是作为构造函数(link),该函数的行为都相同:
当 Array 作为函数而不是构造函数调用时,它还会创建并初始化一个新的Array对象。因此,函数调用 Array(...)等效于具有相同参数的对象创建表达式 new Array(...)。
由于TypeScript假设_super.apply(this, arguments)
将返回this
,但是返回一个新实例,所以您的a
变量实际上包含一个纯Array
实例,而不是一个{{ 1}}。
顺便说一句,我提到的关于ExtArray
的特殊行为也适用于其他本机对象,例如Array
。
对于RegExp
本身,它是为了正确处理Array(...)
的调用,但是由于它是通过super(...)
间接调用的,因此不会收到正确的{{1} },这是行不通的。
编译器对此的潜在解决方案可能是调用apply
或将其反映为new.target
。
答案 1 :(得分:0)
我基于working solution找到了another SO thread solution。诀窍是添加以下行:
Object.setPrototypeOf(this, ExtArray.prototype);
到构造函数。一切看起来像这样:
class ExtArray<T> extends Array<T> {
constructor(...args) {
super(...args)
Object.setPrototypeOf(this, ExtArray.prototype);
}
log() {
console.log(this)
}
}
var a = new ExtArray(1,2,3)
a.log()