【问题标题】:Dynamically calling a static method动态调用静态方法
【发布时间】:2017-02-16 18:08:29
【问题描述】:

在一个类中有几个static 方法,调用的方法将在运行时决定。如何动态调用此方法?

export default class channel {

    // METHOD THAT WILL DYNAMICALLY CALL OTHER STATIC METHODS
    private static methodMap = {
        'channel-create' : 'create',
        'channel-user-count' : 'userCount',
        'channel-close' : 'close'
    };

    public static do(commandType:string,params: any) {
        if(channel.methodMap.hasOwnProperty(commandType)) {
            // GET NAME OF THE METHOD
            let method = channel.methodMap[commandType];
            // CALL METHOD ON THE FLY
            //return channel.call(method,params);
            // channel.userCount(params);
        }
    }
    /**
     * Adds channel to available channel list
     */
    private static create(channelName:string) {

    }

    /**
     * Returns count of users in the channel
     */
    private static userCount(channelName:string) {

    }

}

【问题讨论】:

  • 你的解决方案有什么问题?
  • @nrabinowitz 我没有。 call 方法抛出错误 TypeError: Class constructor channel cannot be invoked without 'new'

标签: javascript typescript static


【解决方案1】:

您可以使用Classname['methodName'](param) 动态调用方法。与您的情况一样,您可以将create 方法调用为Channel['create']('MyChannel')

下面是工作示例:Typescript Playground

class Channel {

    private static methodMap = {
        'channel-create' : 'create',
        'channel-user-count' : 'userCount',
        'channel-close' : 'close'
    };

    private static create(channelName:string) {
        alert('Called with ' + channelName);
    }

    private static userCount(channelName:string) {
        alert('Usercount called with ' + channelName);
    }

    public static do(commandType: string, params: any) {
        if(Channel.methodMap.hasOwnProperty(commandType)) {
            let method = Channel.methodMap[commandType];

            return Channel[method](params);
        }
    }
}

Channel.do('channel-create', 'MyChannel');
Channel.do('channel-user-count', 1000);

编辑:尽管上述方法有效,但正如@Ryan 在他的回答中提到的那样,直接在地图中提供功能要干净得多。

private static methodMap: MethodMap = {
    'channel-create': Channel.create,
    'channel-user-count': Channel.userCount,
    'channel-close': Channel.close,
};

【讨论】:

    【解决方案2】:

    将函数直接存储在地图中:

    type MethodMap = { [name: string]: (any) => void };
    
    private static methodMap: MethodMap = {
        'channel-create': Channel.create,
        'channel-user-count': Channel.userCount,
        'channel-close': Channel.close,
    };
    
    public static do(commandType: string, params: any) {
        if (channel.methodMap.hasOwnProperty(commandType)) {
            const method = channel.methodMap[commandType];
            method(params);
        }
    }
    

    【讨论】:

      【解决方案3】:

      要添加到@HardikModha 的答案,您还可以让编译器根据可能的值检查commandType:

      public static do(commandType: keyof typeof Channel.methodMap, params: any) {
          if(Channel.methodMap.hasOwnProperty(commandType)) {
              let method = Channel.methodMap[commandType];
      
              return Channel[method](params);
          }
      }
      ...
      
      Channel.do('channel-create', 'MyChannel'); // fine
      Channel.do('channel-created', 'MyChannel'); // error
      

      (code in playground)

      【讨论】:

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