Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用ES6类扩展内置数组-方法不是函数错误_Javascript_Typescript - Fatal编程技术网

Javascript 使用ES6类扩展内置数组-方法不是函数错误

Javascript 使用ES6类扩展内置数组-方法不是函数错误,javascript,typescript,Javascript,Typescript,我正在尝试扩展内置数组类并创建基于本机数组类的自定义集合 我可以用自定义名称创建集合,它工作得很好,但我不能使用自定义方法。如果我使用findAnimal方法,它会告诉我方法不是一个函数错误。如果我记录收集和检查原型,我就看不到我的自定义方法 我意识到我将代码向下传输到es5中,如果我没有,工作正常,ts编译器的es5降级代码就会出现问题 如果我们使用babel将代码降级为es5,则传输的代码工作得很好。要么ts编译器在传输代码时遗漏了一些内容,要么我遗漏了一些重要的配置 interface A

我正在尝试扩展内置数组类并创建基于本机数组类的自定义集合

我可以用自定义名称创建集合,它工作得很好,但我不能使用自定义方法。如果我使用findAnimal方法,它会告诉我
方法不是一个函数
错误。如果我记录收集和检查原型,我就看不到我的自定义方法

我意识到我将代码向下传输到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 function
界面动物{ 名称:字符串; 重量:数字 } 类AnimalCollection扩展了数组{ 构造函数(名称,…项){ 超级(…项目); Object.defineProperty(此“名称”{ 可枚举:false, 可写:false, 值:name }) } findAnimal(名称):动物{ 返回此值。查找(a=>a.name==name)| null; } } 常量动物数组=[ {名称:'TD-23',重量:60}, {名称:'TD-25',重量:50}, {名称:'TXD-26',重量:120}, {名称:'TYD-26',重量:40} ]; 常数动物=新动物集合('Deers',…动物阵列) 控制台日志(animals.findAnimal('TD-23')); //未捕获的TypeError:animals.findAnimal不是函数 ES5降级

var uu extends=(this&&this.u extends)| |(函数(){
var extendStatics=功能(d,b){
extendStatics=Object.setPrototypeOf||
({uuuuu proto}数组和函数(d,b){d.{uuuu proto}的实例[]}||
函数(d,b){for(var p in b)如果(b.hasOwnProperty(p))d[p]=b[p];};
返回extendStatics(d,b);
};
返回函数(d,b){
扩展静态(d,b);
函数{this.constructor=d;}
d、 prototype=b==null?对象。创建(b):(_uu.prototype=b.prototype,new_u());
};
})();
var _spreadArrays=(this&&this._spreadArrays)| |函数(){
对于(var s=0,i=0,il=arguments.length;i
我可以看出您缺少了一些
任何
,这是适合我的代码:

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'));

它不会产生任何错误

导致错误的是您编写函数的方式

界面动物{ 名称:字符串; 重量:数字 } 类AnimalCollection扩展了数组{ 构造函数(名称,…项){ 超级(…项目); Object.defineProperty(此“名称”{ 可枚举:false, 可写:false, 值:name }) } findAnimal:Animal=(名称:String)=>{ 返回此值。查找(a=>a.name==name)| null; } } 常量动物数组=[ {名称:'TD-23',重量:60}, {名称:'TD-25',重量:50}, {名称:'TXD-26',重量:120}, {名称:'TYD-26',重量:40} ]; 常数动物=新动物集合('Deers',…动物阵列) 控制台日志(animals.findAnimal('TD-23')); //未捕获的类型错误:animals.FindImal不是函数更新的答案 为了回答修改后的问题,TypeScript不允许您扩展内置程序,如
数组
错误
等。原因是

在ES2015中,返回对象的构造函数隐式替换 对于super(…)的任何调用方,此函数的值。这是必要的 生成的构造函数代码,用于捕获 超级(…)并将其替换为此

因此,子类化错误、数组和其他可能不再有效 正如所料。这是由于构造函数为 错误、数组等使用ECMAScript 6的new.target来调整 原型链;但是,没有办法确保 调用ECMAScript 5中的构造函数时使用new.target。其他 默认情况下,底层编译器通常具有相同的限制

所以,如果您必须在ES5环境下扩展内置的
数组
,那么您可以尝试Babel来编译代码。然而,请注意,它也有它的局限性

诸如Date、Array、DOM等内置类无法正确 由于ES5(用于转换类)中的限制而子类化 插件)。您可以尝试使用babel插件转换内置扩展 基于Object.setPrototypeOf和Reflect.construct,但它也具有 一些限制

旧答案 虽然代码本身是完美的,并且在浏览器中也可以很好地执行,但我认为您得到的错误是因为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'));
但是,如果我们将
tsconfig.json
中的
目标设置为som
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'));