转换的JavaScript箭头功能正常功能
我目前经历的角度教程和整个下面的代码来:转换的JavaScript箭头功能正常功能
getHero(id: number): Promise<Hero> {
return this.getHeroes().then(heroes => heroes.find(hero => hero.id === id));
}
出于好奇,我决定用一个正常功能重写回调函数:
getHero(id: number): Promise<Hero> {
return this.getHeroes().then(heroes => heroes.find(this.findHero, id));
}
findHero(hero: Hero, index: number, array: Hero[]): boolean {
if(hero.id === this.id){
return true;
}else{
return false;
}
}
但是,这给我的错误Property 'id' does not exist on type 'HeroService'.
我怎么可能引用传递给我的callb的id
参数ack功能?
id
(number)属性被定义为函数getHero
的自变量,因此在您的函数findHero
中不可用。您尝试使用this.id
,但编译器告诉您这样的属性不会在您的类HeroService
中退出,这当然是正确的,就好像您希望将该属性作为服务的一部分一样,那么您将不得不执行类似这在你的getHero
方法中。
getHero(id: number, ...etc) {
this.id = id;
// etc.
}
但是,这会为你带来另一个问题:作为你的方法getHeroes
似乎是异步代码(我可以告诉大家,因为它返回一个Promise
)这种做法将导致您的并发问题头痛时,你的方法getHero
是从应用程序的不同部分调用两次(或更多次)。第一个getHero
呼叫将设置this.id
到x
但在此期间,异步代码运行时,另一个呼叫getHero
将设置为y
,使回拨findHero
运行响应第一次调用使用不正确的值为id
(具体来说,它将读取y
作为this.id
的值)。
因此...长话短说。您可能想要了解关于CLOSURES的更多信息,以及它们为什么对JavaScript非常重要。简短的回答你的问题,使用此:
getHero(id: number): Promise<Hero> {
return this.getHeroes().then(heroes => heroes.find(this.findHero.bind(this, id));
}
,以及为什么需要这就是this
是不是你作为使用的功能自动传递定义回调findHero
作为
findHero(idToFind: number, hero: Hero, index, array: Hero[]) {
return hero.id === idToFind;
}
原因其他功能(或方法,如在这种情况下)的参数。因此,通过使用bind
,您明确地绑定了此功能的this
,以便每当您在findHero
中使用this
时,它都指向正确的对象。的bind
第二个参数是有约束力的id
您正在寻找的功能findHero
的每一个电话,这样,每当通过bind
返回的函数被调用它发生两件事情:
- 的
this
势必HeroService
。 - 除了参数 函数通常会收到的参数之外,您还绑定了另一个参数 ,该参数将被自动注入到调用该函数的参数 中。
只是一个小小的音符...您使用打字稿,所以this
参数在bind
是没有意义的,为打字稿自动绑定在你的类当前实例的所有方法,但你需要它在这种情况下,因为你也想要绑定第二个参数(找到id
)。
我希望我帮了忙。
你好@damianmr,谢谢你提供的内容丰富的评论,确实有帮助。我在这里看看关闭:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures我从中学到了很多东西。 我只能在你提供的代码中改变一点。 'findHero'函数的参数必须按以下顺序写入: 'findHero(idToFind:number,hero:Hero,index:number,array:Hero []):布尔值{' 我不确定为什么和当前谷歌搜索答案。 谢谢, – kiseragi
找到原因。绑定的参数被添加到了有界的函数中:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind 谢谢, – kiseragi
@kiseragi我会更新答案,我从我的记忆中写下来,并认为它被添加到结尾:) – damianmr