簡體   English   中英

TypeScript數組 <T> 遺產

[英]TypeScript Array<T> inheritance

我有一些實驗性代碼繼承自Array<T> ...

class SuperArray<T> extends Array<T> {
    constructor(...items) {
        super(...items);
    }

    public clear(): void {
        while (this.length > 0) {
            this.pop();
        }
    }
}

var array = new SuperArray("Matt", "Mark", "Luke", "John");

array.clear();

操場

我添加了clear方法只是為了說明問題。 當它被編譯並在瀏覽器中運行時,我得到...

TypeError:array.clear不是函數

這在TypeScript中如何完全有效,而在JavaScript中卻無效,有沒有辦法解決此問題?

順便說一句,這是TS2.1中的重大變化

TS文檔提供了有關在構造函數中更改原型的建議

constructor(...items) {
    super(...items);
    Object.setPrototypeOf(this, SuperArray.prototype);
}

定位es5時,您的代碼將編譯為以下代碼:

var SuperArray = (function (_super) {
    __extends(SuperArray, _super);
    function SuperArray() {
        var items = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            items[_i] = arguments[_i];
        }
        return _super.apply(this, items) || this;
    }
    SuperArray.prototype.clear = function () {
        while (this.length > 0) {
            this.pop();
        }
    };
    return SuperArray;
}(Array));
var array = new SuperArray("Matt", "Mark", "Luke", "John");
array.clear();

不可能像這樣擴展本機對象,這就是為什么會出現此錯誤的原因。
如果您以es6為目標,那么編譯后的js將如下所示:

class SuperArray extends Array {
    constructor(...items) {
        super(...items);
    }
    clear() {
        while (this.length > 0) {
            this.pop();
        }
    }
}
var array = new SuperArray("Matt", "Mark", "Luke", "John");
array.clear();

這樣就可以正常工作(如果您在支持es6類的瀏覽器中運行它)。


編輯

我將僅在ECMAScript 6中粘貼文章Subclassing Builtins的部分內容,其中解釋了為什么無法使用es5完成es5

分配障礙:MyArray分配錯誤類型的對象
數組實例很特殊– ECMAScript 6規范稱它們為奇異的。 他們對屬性長度的處理無法通過常規JavaScript復制。 如果調用構造函數MyArray,則將創建MyArray的實例,而不是外部對象。

初始化障礙:MyArray無法使用Array進行初始化
不可能通過this將現有對象交給Array –它完全忽略了它並始終創建一個新實例。

從Typescript 2.2開始,您可以從構造函數訪問new.target

因此,您可以在調用super()之后進行以下調用:

Object.setPrototypeOf(this, new.target.prototype);

應該解決原型鏈問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM