微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

对于一组实例,对于每个实例,如何通过该方法的名称调用某个方法?

如何解决对于一组实例,对于每个实例,如何通过该方法的名称调用某个方法?

我试图将 Particle 类的函数 behappy() 作为 ParticleSystem 类的 applyBehavior 函数的参数传递。我错过了一些语法吗?我不明白我的电话有什么问题。

这里有最少的可重现代码here

class ParticleSystem{
  constructor(){
    this.particles = [];
    this.numberOfParticles = 10;
    for(let i = 0; i < this.numberOfParticles; i++){
      this.particles.push(new Particle());
    }
  }
  
  applyBehavior(behavior,message){
    for(let i = 0; i < this.numberOfParticles; i++){
      this.particles[i].behavior(message);
    }
  }
}

class Particle{
  constructor(){}
  behappy(message){
    print(message);
  }
}

let particlesys = new ParticleSystem();
particlesys.applyBehavior(behappy,"i am happy Now");

预期输出应该是:

“我现在很高兴”“我现在很高兴”“我现在很高兴”“我现在很高兴”“我 我现在很开心”“我现在很开心”“我现在很开心”“我现在很开心”“我现在很开心” 现在很开心”“我现在很开心”

解决方法

如果粒子系统的 applyBehavior 应该调用粒子的方法,首先应该将此方法重命名为 callBehaviorexecuteBehavior 或更好的是 executeParticles 和其次需要提供粒子的方法/行为名称作为第一个参数而不是函数引用。

编辑

正如 Bergi 已经指出的那样,一个原因必须假设 Particle 实例的任何方法最有可能在 Particle 实例的 this上下文。

然后,ParticleSystemexecuteParticles 方法必须以一种向任何可访问的 Particle 方法显式提供此类上下文的方式实现。由于函数本身就是对象,因此它们带有两种方法来实现... callapply。可以为这两种方法提供一个目标对象。此目标对象确实成为通过 call/apply 调用的任何方法/函数的上下文。

示例代码进行了相应的更改,以显示此用例...

class ParticleSystem{
  constructor(){
    this.particles = [];
    this.numberOfParticles = 10;
    for(let i = 0; i < this.numberOfParticles; i++){
      this.particles.push(new Particle(i));
    }
  }
  executeParticles(behaviorName,message){
    // for(let i = 0; i < this.numberOfParticles; i++){
    //  this.particles[i][behaviorName](message);
    // }
    this.particles.forEach(particle => {
      const behavior = particle && particle[behaviorName];
      if (typeof behavior === 'function') {

        // MDN: "Function.prototype.call"
        // see: [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call]

        behavior.call(particle,message);
      }
    });
  }
}

class Particle{
  constructor(idx){
    this.id = `particle_${ idx }`;
  }
  behappy(message){
    console.log(`${ this.id } logs ... "${ message }"`);
  }
}

let particlesys = new ParticleSystem();
particlesys.executeParticles('behappy',"I'am happy now.");
.as-console-wrapper { min-height: 100%!important; top: 0; }

最通用的 executeParticles 实现是使用 apply ...

class ParticleSystem{
  constructor(){
    this.particles = [];
    this.numberOfParticles = 10;
    for(let i = 0; i < this.numberOfParticles; i++){
      this.particles.push(new Particle(i));
    }
  }
  executeParticles(behaviorName,...args){
    this.particles.forEach(particle => {
      const behavior = particle && particle[behaviorName];
      if (typeof behavior === 'function') {

        behavior.apply(particle,args);
      }
    });
  }
}

class Particle{
  constructor(idx){
    this.id = `particle_${ idx }`;
  }
  behappy(message){
    console.log(`${ this.id } logs ... "${ message }"`);
  }
}

let particlesys = new ParticleSystem();
particlesys.executeParticles('behappy',"I'am happy now.");
.as-console-wrapper { min-height: 100%!important; top: 0; }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。