【问题标题】:Is it possible to use variable to call a function as parameter javascript [duplicate]是否可以使用变量作为参数调用函数javascript [重复]
【发布时间】:2019-10-10 20:03:33
【问题描述】:

假设需要使用条件,它做同样的事情,但调用不同的方法。

const c = true; // for example sake 
let b = '';
if (c) {
  b = 'method1';
} else {
  b = 'method2';
}

function a(){
   this.service.b(filter).subscribe((result) =>{
      // stuff happens
   });
}

是否可以使用变量b作为动态变量来调用服务中的方法?

Stackblitz example

根据例子更新了sn-p,我可以做如下的:

if (this.title == 'Students') {
  this.studentService.getStudents().then(results=> this.lists = results);
} else {
  this.studentService.getCandidates().then(results => this.lists = results);
}

但是有没有可能做这样的事情:

this.studentService.get[this.title]().then(results=> this.lists = results);

正如副本所说,它不会那样工作。

【问题讨论】:

  • service.b 应该是service[b]
  • @Rajesh 似乎不是访问服务的方式。我的意思是,如果我使用像this.service.method1(filter).....this.service.method2(filter).... 这样的传统方式,过程相同。它可以完成这项工作,但它不是 DRY。
  • 根据我的理解,您在服务对象中有method1/method2,您需要调用它,但方法的名称存储在b 中。如果这是正确的,service[b] 将返回方法的引用并添加 (...) 将调用它。所以除非我理解错了,否则它应该可以工作
  • 提供一个更完整的示例,其中“method1”和“method2”以您期望的方式存在。实现一个基本示例,其中 'this' 和 'this.service' 有意义,这样我们就可以了解您如何尝试访问 method1 和 method2
  • 好的,如果this.title可以等于'Students'或'Candidates',并且this.studentService有方法getStudentsgetCandidates,那么你可以做this.studentService[`get${this.title}`]()

标签: javascript angular typescript


【解决方案1】:

您可以使用索引访问来获取 Typescript 中的特定方法,诀窍是索引参数的类型。如果类型没有索引签名(类通常不应该),那么索引参数必须是keyof 类型的

class DoStuff {
    messageA() : Promise<string> {
        return new Promise(r=> r("messsageA"));
    }

    messageB() : Promise<string> {
        return new Promise(r=> r("messsageB"));
    }
}

let k: keyof DoStuff = Math.random()> 0.5 ? "messageA" : "messageB";
let o = new DoStuff();
o[k]().then(m=> console.log(m))

如果类包含更多签名不兼容的方法,您可能无法调用o[k] 的结果。您可以通过列出要索引的确切方法(`let k :"messageA" | "messageB")来解决此问题。或者您可以使用过滤键的类型:

class DoStuff {
    messageA() : Promise<string> {
        return new Promise(r=> r("messsageA"));
    }

    messageB() : Promise<string> {
        return new Promise(r=> r("messsageB"));
    }
    util(): string { return ""}
}

let k: keyof DoStuff = (Math.random()> 0.5 ?"messageA" : "messageB") as keyof DoStuff;
let o = new DoStuff();
o[k]().then(m=> console.log(m)) //error

type FilterKeysByType<T, V> = { [P in keyof T] : T[P] extends V ? P : never}[keyof T]
let kok:FilterKeysByType<DoStuff, ()=> Promise<string>>  =  (Math.random()> 0.5 ?"messageA" : "messageB") as FilterKeysByType<DoStuff, ()=> Promise<string>>;
o[kok]().then(m=> console.log(m)) //error

【讨论】:

    【解决方案2】:

    是的,但您可以将函数分配给变量,而不是使其成为字符串,例如

    function bla() {
      console.log('bla');
    }
    let b = bla;
    b();
    

    由于我看到一些反对意见,我应该详细说明这一点。如果你想在this.service 上调用b,你不能像上面描述的那样做。

    对象上的函数存储在具有函数名称的键下。您应该在此处使用字符串。例如

    let thing = {};
    thing.a = function() {}
    let b = 'a';
    thing[b]();
    

    如果您的对象是一个类,则同样适用,例如

    class Thing {
     bla() {}
    }
    let a = new Thing();
    let b = "bla";
    a[b]();
    

    【讨论】:

      猜你喜欢
      • 2012-12-02
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      • 2018-10-20
      • 2016-07-03
      相关资源
      最近更新 更多