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