【问题标题】:Map of functions in javascript?javascript中的函数映射?
【发布时间】:2011-09-12 09:26:19
【问题描述】:

我有一个上下文菜单,可以触发不同的 javascript 函数。 选择函数的幼稚解决方案如下所示:

function(action, el, pos) {
    switch(action)
    {
        case "export_selected_to_excel":
            exportSelectedToExcel(el);
            break;

        etc..
    }
}

我想要一个函数映射,以便我可以将方法简化为类似于以下内容:

function(action, el, pos) {
    menuAction[action](el);
}

我这样定义数组:

function exportSelectedToExcel(id){
   //stuff...
}

var menuAction = new Array();
menuAction["export_selected_to_excel"] = exportSelectedToExcel;

这似乎工作正常,感觉像是一个合理的解决方案。

在 javascript 中这样做有什么缺点吗?
还有更好的方法吗?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    你的想法很好,但你不应该使用数组作为关联映射,因为它们不是关联的(参见例如Mastering Javascript Arrays)。当您执行var a = []; a["x"] = y 时,实际上您将属性x 分配给对象a。因此,它在之后成立:a.length == 0 and a.x == y

    您应该只用对象替换Array 以获得关联映射:

    var menuAction = {};
    menuAction["export_selected_to_excel"] = exportSelectedToExcel;
    // or
    menuAction.export_selected_to_excel = exportSelectedToExcel;
    // or
    menuAction.export_selected_to_excel = function(id) {...};
    

    或:

    var menuAction = {
        export_selected_to_excel: exportSelectedToExcel,
        export_x: exportX   // etc
    }
    

    【讨论】:

      【解决方案2】:

      如果你这样做,函数将指向另一个函数,从而产生一些开销,你也可以直接在对象内部定义函数,例如:

      var menuAction = {};
      menuAction.export_selected_to_excel = function (id) {
          // stuff
      }
      

      为了确保函数存在,您可以这样做:

      var action = 'export_selected_to_excel';
      if(typeof menuAction[action] == 'function')
      {
          // call function
      }
      

      【讨论】:

      • 定义是按字面复制的,还是按照我的方式对函数的引用?
      • 这是完全合法的,我在我的代码中使用了相同的逻辑。没有函数不会“存在两次”,你只有函数和指向它的“指针”。
      【解决方案3】:

      如果真的是函数名可以直接从字符串派生,例如,

      export_selected_to_excel   => exportSelectedToExcel
      compute_selected           => computeSelected
      ...
      

      ...那么,您可以动态生成 fn 名称并动态调用它们,而不是使用关联数组。

      使用此问题的答案 (Convert hyphens to camel case (camelCase)) 转换名称。

      然后,使用此问题的答案 (How to execute a JavaScript function when I have its name as a string) 调用该函数。请务必通过typeof 测试验证window[functionName] 是否为实际函数。

      【讨论】:

      • 实际上,我可以将字符串和函数命名为任何名称。很酷的解决方案,但开销似乎有点不必要。我喜欢它,但我不相信它值得。
      • @Cheeso:如果你事先知道这些功能,我认为这是不必要的低效。
      【解决方案4】:

      我不认为有很大的缺点。 实际上,您尝试做的事情与定义对象并在内部声明函数时所做的事情相似。

      例如:

      var menuAction = {
          function action1(el) {
             // ...
          },
          function action2(el) {
             //...
          },
      
          // ...       
      }
      

      唯一的区别是,在这种情况下,您定义的函数不是在对象声明中,而是使用关联数组表示法的后验。

      【讨论】:

        猜你喜欢
        • 2011-08-04
        • 2019-07-13
        • 2019-01-31
        • 1970-01-01
        • 2017-10-25
        • 1970-01-01
        • 2012-07-24
        • 2017-01-19
        • 2010-10-09
        相关资源
        最近更新 更多