亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Extending Built-in Array With ES6 Classes

Extending Built-in Array With ES6 Classes

森欄 2022-11-27 16:38:22
我正在嘗試擴展內置數組類并創建基于本機數組類的自定義集合。我可以使用自定義名稱創建集合,效果很好,但我無法使用我的自定義方法。如果我使用 findAnimal 方法,它會給我method is not a function錯誤。如果我記錄收集并檢查原型,我看不到我的自定義方法。我意識到我將代碼轉譯為 es5,如果沒有,效果很好,ts 編譯器的 es5 降級代碼會出現問題。如果我們使用 babel 將代碼降級為 es5,轉譯后的代碼運行良好。要么是 ts 編譯器在轉譯代碼時遺漏了一些東西,要么是我遺漏了一些重要的配置。interface Animal {    name: string;    weight: number}class AnimalCollection extends Array <Animal> {    constructor(name, ...items) {        super(...items);        Object.defineProperty(this, 'name', {            enumerable: false,            writable: false,            value: name        })    }    findAnimal(name): Animal {        return this.find(a => a.name === name) || null;    }}const animalsArray = [    {name: 'TD-23', weight: 60},    {name: 'TD-25', weight: 50},    {name: 'TXD-26', weight: 120},    {name: 'TYD-26', weight: 40}];const animals = new AnimalCollection('Deers', ...animalsArray)console.log(animals.findAnimal('TD-23'));// Uncaught TypeError: animals.findAnimal is not a functionES5降級var __extends = (this && this.__extends) || (function () {    var extendStatics = function (d, b) {        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 extendStatics(d, b);    };    return function (d, b) {        extendStatics(d, b);        function __() { this.constructor = d; }        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());    };})();var __spreadArrays = (this && this.__spreadArrays) || function () {    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;    for (var r = Array(s), k = 0, i = 0; i < il; i++)        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)            r[k] = a[j];    return r;};
查看完整描述

3 回答

?
慕神8447489

TA貢獻1780條經驗 獲得超1個贊

更新的答案

要回答您修改后的問題,TypeScript 不允許您擴展內置函數ArrayError。原因寫在這里。

在 ES2015 中,返回對象的構造函數隱式地將 this 的值替換為 super(...) 的任何調用者。生成的構造函數代碼有必要捕獲 super(...) 的任何潛在返回值并將其替換為這個。

因此,子類化 Error、Array 和其他類可能不再按預期工作。這是由于Error、Array等構造函數使用了ECMAScript 6的new.target來調整原型鏈;但是,在 ECMAScript 5 中調用構造函數時無法確保 new.target 的值。默認情況下,其他下層編譯器通常具有相同的限制。

所以如果你必須在 ES5 環境下擴展內置Array,那么你可以嘗試使用 Babel 來編譯你的代碼。但是請注意,它具有此處所述的限制。

由于 ES5(對于 transform-classes 插件)的限制,諸如 Date、Array、DOM 等內置類不能被正確地子類化。你可以嘗試使用基于 Object.setPrototypeOf 和 Reflect.construct 的 babel-plugin-transform-builtin-extend,但它也有一些限制。

舊答案

雖然代碼本身可以很好地找到并且在瀏覽器中也可以正常執行,但我認為您遇到的錯誤是由于 TypeScript 編譯器造成的。

對于源代碼

interface Animal {

    name: string;

    weight: number

}


class AnimalCollection extends Array <Animal> {

    constructor(name: string, ...items: Animal[]) {

        super(...items);


        Object.defineProperty(this, 'name', {

            enumerable: false,

            writable: false,

            value: name

        })

    }


    findAnimal(name:string): Animal | null {

        return this.find(a => a.name === name) || null;

    }

}


const animalsArray = [

    {name: 'TD-23', weight: 60},

    {name: 'TD-25', weight: 50},

    {name: 'TXD-26', weight: 120},

    {name: 'TYD-26', weight: 40}

];


const animals = new AnimalCollection('Deers', ...animalsArray)


console.log(animals.findAnimal('TD-23'));

如果編譯器目標選項設置為ES5,那么它會生成破壞實現的代碼。它生成的代碼是


"use strict";

var __extends = (this && this.__extends) || (function () {

    var extendStatics = function (d, b) {

        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 extendStatics(d, b);

    };

    return function (d, b) {

        extendStatics(d, b);

        function __() { this.constructor = d; }

        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());

    };

})();

var __spreadArrays = (this && this.__spreadArrays) || function () {

    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;

    for (var r = Array(s), k = 0, i = 0; i < il; i++)

        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)

            r[k] = a[j];

    return r;

};

var AnimalCollection = /** @class */ (function (_super) {

    __extends(AnimalCollection, _super);

    function AnimalCollection(name) {

        var items = [];

        for (var _i = 1; _i < arguments.length; _i++) {

            items[_i - 1] = arguments[_i];

        }

        var _this = _super.apply(this, items) || this;

        Object.defineProperty(_this, 'name', {

            enumerable: false,

            writable: false,

            value: name

        });

        return _this;

    }

    AnimalCollection.prototype.findAnimal = function (name) {

        return this.find(function (a) { return a.name === name; }) || null;

    };

    return AnimalCollection;

}(Array));

var animalsArray = [

    { name: 'TD-23', weight: 60 },

    { name: 'TD-25', weight: 50 },

    { name: 'TXD-26', weight: 120 },

    { name: 'TYD-26', weight: 40 }

];

var animals = new (AnimalCollection.bind.apply(AnimalCollection, __spreadArrays([void 0, 'Deers'], animalsArray)))();

console.log(animals.findAnimal('TD-23'));

但是,如果我們將targetin設置tsconfig.json為等于或大于ES2015,那么它生成的代碼是


"use strict";

class AnimalCollection extends Array {

    constructor(name, ...items) {

        super(...items);

        Object.defineProperty(this, 'name', {

            enumerable: false,

            writable: false,

            value: name

        });

    }

    findAnimal(name) {

        return this.find(a => a.name === name) || null;

    }

}

const animalsArray = [

    { name: 'TD-23', weight: 60 },

    { name: 'TD-25', weight: 50 },

    { name: 'TXD-26', weight: 120 },

    { name: 'TYD-26', weight: 40 }

];

const animals = new AnimalCollection('Deers', ...animalsArray);

console.log(animals.findAnimal('TD-23'));

這當然有效。所以我認為 ES5 或更低版本的 TypeScript 編譯器存在問題,這會破壞實現。我試過使用Babel 進行編譯,它適用于 ES5。


查看完整回答
反對 回復 2022-11-27
?
慕森卡

TA貢獻1806條經驗 獲得超8個贊

導致錯誤的是您編寫函數的方式


interface Animal {

    name: string;

    weight: number

}


class AnimalCollection extends Array <Animal> {

    constructor(name, ...items) {

        super(...items);


        Object.defineProperty(this, 'name', {

            enumerable: false,

            writable: false,

            value: name

        })

    }


    findAnimal:Animal=(name:String)=> {

        return this.find(a => a.name === name) || null;

    }

}


const animalsArray = [

    {name: 'TD-23', weight: 60},

    {name: 'TD-25', weight: 50},

    {name: 'TXD-26', weight: 120},

    {name: 'TYD-26', weight: 40}

];


const animals = new AnimalCollection('Deers', ...animalsArray)


console.log(animals.findAnimal('TD-23'));

// Uncaught TypeError: animals.findAnimal is not a function


查看完整回答
反對 回復 2022-11-27
?
慕哥9229398

TA貢獻1877條經驗 獲得超6個贊

我可以看到你遺漏了一些any,這是對我有用的代碼:


interface Animal {

    name: string;

    weight: number

}


class AnimalCollection extends Array <Animal> {

    constructor(name: string, ...items : Array <Animal>) { // <-- missing types

        super(...items);


        Object.defineProperty(this, 'name', {

            enumerable: false,

            writable: false,

            value: name

        })

    }


    findAnimal(name : any): Animal|null { // <-- missing null

        return this.find(a => a.name === name) || null;

    }

}


const animalsArray = [

    {name: 'TD-23', weight: 60},

    {name: 'TD-25', weight: 50},

    {name: 'TXD-26', weight: 120},

    {name: 'TYD-26', weight: 40}

];


const animals = new AnimalCollection('Deers', ...animalsArray)


console.log(animals.findAnimal('TD-23'));

但是此代碼生成以下 JS:


"use strict";

class AnimalCollection extends Array {

    constructor(name, ...items) {

        super(...items);

        Object.defineProperty(this, 'name', {

            enumerable: false,

            writable: false,

            value: name

        });

    }

    findAnimal(name) {

        return this.find(a => a.name === name) || null;

    }

}

const animalsArray = [

    { name: 'TD-23', weight: 60 },

    { name: 'TD-25', weight: 50 },

    { name: 'TXD-26', weight: 120 },

    { name: 'TYD-26', weight: 40 }

];

const animals = new AnimalCollection('Deers', ...animalsArray);

console.log(animals.findAnimal('TD-23'));

這不會產生任何錯誤


查看完整回答
反對 回復 2022-11-27
  • 3 回答
  • 0 關注
  • 160 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號