【问题标题】:Javascript Array of FunctionsJavascript 函数数组
【发布时间】:2011-06-21 22:58:56
【问题描述】:
var array_of_functions = [
    first_function('a string'),
    second_function('a string'),
    third_function('a string'),
    forth_function('a string')
]

array_of_functions[0];

这并没有按预期工作,因为数组中的每个函数都是在创建数组时执行的。

执行数组中任何函数的正确方法是:

array_of_functions[0];  // or, array_of_functions[1] etc.

谢谢!

【问题讨论】:

  • 在填充数组时是否需要知道'a string',或者函数的调用者可以将其传入吗?
  • 我很想了解更多关于您要完成的工作的详细信息,因为可能有更好的方法来处理这个问题。
  • “函数数组”——或者我们喜欢称它为带有方法的对象
  • 你不认为你应该提供更多细节吗?可能有更好的方法来处理这个..

标签: javascript arrays function


【解决方案1】:
var array_of_functions = [
    first_function,
    second_function,
    third_function,
    forth_function
]

然后当你想执行数组中的给定函数时:

array_of_functions[0]('a string');

【讨论】:

  • 提示:请记住将() 放在array_of_functions[0] 之后,即使它是空的。我花了大约 20 分钟来找出“为什么那行不通”。
  • 像魅力一样工作!
  • 如何通过传递像“firstFunction”这样的字符串值来获取函数的索引,以便它可以是动态的?
【解决方案2】:

如果没有更多关于您要完成的工作的详细信息,我们只是在猜测。但是您也许可以使用对象表示法来做这样的事情......

var myFuncs = {
  firstFunc: function(string) {
    // do something
  },

  secondFunc: function(string) {
    // do something
  },

  thirdFunc: function(string) {
    // do something
  }
}

并打电话给其中一个......

myFuncs.firstFunc('a string')

【讨论】:

  • 我认为这对开发人员更友好,因为我们不需要记住函数索引。而且,如果我们想在特定索引处推送任何函数,那么它会导致它旁边的所有函数的索引发生变化。所以最好用这个
【解决方案3】:

或者只是:

var myFuncs = {
  firstFun: function(string) {
    // do something
  },

  secondFunc: function(string) {
    // do something
  },

  thirdFunc: function(string) {
    // do something
  }
}

【讨论】:

    【解决方案4】:

    我认为这就是原始海报想要实现的目标:

    var array_of_functions = [
        function() { first_function('a string') },
        function() { second_function('a string') },
        function() { third_function('a string') },
        function() { fourth_function('a string') }
    ]
    
    for (i = 0; i < array_of_functions.length; i++) {
        array_of_functions[i]();
    }
    

    希望这会帮助其他人(比如 20 分钟前的我 :-) 寻找有关如何在数组中调用 JS 函数的任何提示。

    【讨论】:

    • 这正是我所需要的,因为它允许我更改参数调用,假设我的函数不都采用相同的参数:P
    【解决方案5】:

    这是正确的

    var array_of_functions = {
                "all": function(flag) { 
                    console.log(1+flag); 
                  },
                    "cic": function(flag) { 
                    console.log(13+flag); 
                  }                     
            };
    
    array_of_functions.all(27);
    array_of_functions.cic(7);
    

    【讨论】:

    • 您确定要回答的this is the question 吗?不相关。
    • @Bergi 实际上是这样。用array_of_functions 替换答案的opera,你得到了同样的结果。现在怎么样?
    • @Jesse 谢谢,现在我有了发布代码的想法,这是我的第一个回复。
    • 但是 OP 有一个数组,而这是一些对象(具有奇怪的属性名称)?这个答案的新闻是什么,为什么不直接投票给 pjcabrera 或 Robin 的呢?
    • 变量名称混淆。那不是函数数组,而是函数对象
    【解决方案6】:

    我将通过发布一个更简单的方法来补充这个线程,使用shift() Javascript 方法originally described here 在数组中执行各种函数

      var a = function(){ console.log("this is function: a") }
      var b = function(){ console.log("this is function: b") }
      var c = function(){ console.log("this is function: c") }
    
      var foo = [a,b,c];
    
      while (foo.length){
         foo.shift().call();
      }
    

    【讨论】:

      【解决方案7】:
      /* PlanetGreeter */
      
      class PlanetGreeter {
          hello   : { () : void; } [] = [];
          planet_1 : string = "World";
          planet_2 : string = "Mars";
          planet_3 : string = "Venus";
          planet_4 : string = "Uranus";
          planet_5 : string = "Pluto";
          constructor() {
              this.hello.push( () => { this.greet(this.planet_1); } );
              this.hello.push( () => { this.greet(this.planet_2); } );
              this.hello.push( () => { this.greet(this.planet_3); } );
              this.hello.push( () => { this.greet(this.planet_4); } );
              this.hello.push( () => { this.greet(this.planet_5); } );
          } 
          greet(a: string) : void { alert("Hello " + a); }
          greetRandomPlanet() : void { 
              this.hello [ Math.floor( 5 * Math.random() ) ] (); 
          } 
      } 
      new PlanetGreeter().greetRandomPlanet();
      

      【讨论】:

        【解决方案8】:

        也许它对某人有帮助。

        <!DOCTYPE html>
        <html>
           <head lang="en">
              <meta charset="UTF-8">
              <title></title>
              <script type="text/javascript">
                 window.manager = {
                     curHandler: 0,
                     handlers  : []
                 };
                 
                 manager.run = function (n) {
                     this.handlers[this.curHandler](n);
                 };
                 
                 manager.changeHandler = function (n) {
                     if (n >= this.handlers.length || n < 0) {
                         throw new Error('n must be from 0 to ' + (this.handlers.length - 1), n);
                     }
                     this.curHandler = n;
                 };
                 
                 var a = function (n) {
                     console.log("Handler a. Argument value is " + n);
                 };
                 
                 var b = function (n) {
                     console.log("Handler b. Argument value is " + n);
                 };
                 
                 var c = function foo(n) {
                     for (var i=0; i<n; i++) {
                         console.log(i);
                     }
                 };
                 
                 manager.handlers.push(a);
                 manager.handlers.push(b);
                 manager.handlers.push(c);
              </script>
           </head>
           <body>
              <input type="button" onclick="window.manager.run(2)" value="Run handler with parameter 2">
              <input type="button" onclick="window.manager.run(4)" value="Run handler with parameter 4">
              <p>
              <div>
                 <select name="featured" size="1" id="item1">
                    <option value="0">First handler</option>
                    <option value="1">Second handler</option>
                    <option value="2">Third handler</option>
                 </select>
                 <input type="button" onclick="manager.changeHandler(document.getElementById('item1').value);" value="Change handler">
              </div>
              </p>
           </body>
        </html>
        

        【讨论】:

          【解决方案9】:

          它与Darin Dimitrov's 基本相同,但它展示了如何使用它来动态创建和存储函数和参数。 我希望它对你有用:)

          var argsContainer = ['hello', 'you', 'there'];
          var functionsContainer = [];
          
          for (var i = 0; i < argsContainer.length; i++) {
          var currentArg = argsContainer[i]; 
          
            functionsContainer.push(function(currentArg){
              console.log(currentArg);
            });
          };
          
          for (var i = 0; i < functionsContainer.length; i++) {
            functionsContainer[i](argsContainer[i]);
          }

          【讨论】:

          • 无论有多少其他人,都可以添加您的答案。但最好添加一些解释,它与其他的不同/更好
          【解决方案10】:

          如果您正在尝试动态传递回调,您可以将单个对象作为参数传递。这使您可以更好地控制要使用任何参数执行的功能。

          function func_one(arg) {
              console.log(arg)
          };
          
          function func_two(arg) {
              console.log(arg+' make this different')
          };
          
          var obj = {
              callbacks: [func_one, func_two],
              params: ["something", "something else"];
          };
          
          function doSomething(obj) {
              var n = obj.counter
              for (n; n < (obj.callbacks.length - obj.len); n++) {
                  obj.callbacks[n](obj.params[n]);
              }
          };
          
          obj.counter = 0;
          obj.len = 0;
          doSomething(obj); 
          
          //something
          //something else make this different
          
          obj.counter = 1;
          obj.len = 0;
          doSomething(obj);
          
          //something else make this different
          

          【讨论】:

            【解决方案11】:

            一个简单的方法来运行它们:

            [first_function, ..., nth_function].forEach (function(f) {
                f('a string');
            }); 
            

            【讨论】:

              【解决方案12】:

              这些函数数组的问题不是“数组形式”,而是这些函数的调用方式......那么...... 试试这个.. 用一个简单的 eval()...

              array_of_function = ["fx1()","fx2()","fx3()",.."fxN()"]
              var zzz=[];
              for (var i=0; i<array_of_function.length; i++)
                   { var zzz += eval( array_of_function[i] ); }
              

              它在这里工作,没有任何上层在家里做这项工作...... 希望对你有帮助

              【讨论】:

              • 您能否解释一下为什么其他答案对您不起作用,而您的答案又为何起作用?谢谢!
              • 它曾经返回我错误,未定义的函数,或者它们完全没有被 javascript 评估......(为什么我不知道,但这解决了我的问题)
              • 是的,一如既往的糟糕,但是拍摄解决方案,并且非常容易使用,特别是如果它远离“输入”......这里它只是在短时间内解决了内部 javascript 的不可能...... .
              【解决方案13】:

              使用 Function.prototype.bind()

              var array_of_functions = [
                      first_function.bind(null,'a string'),
                      second_function.bind(null,'a string'),
                      third_function.bind(null,'a string'),
                      forth_function.bind(null,'a string')
                  ]
              

              【讨论】:

                【解决方案14】:

                您在上面得到了一些最佳答案。这只是另一个版本。

                var dictFun = {
                     FunOne: function(string) {
                     console.log("first function");
                  },
                
                   FuncTwo: function(string) {
                   console.log("second function");
                 },
                
                  FuncThree: function(string) {
                   console.log("third function");
                }
                

                }

                【讨论】:

                • 问题是函数的数组,而不是对象。
                【解决方案15】:

                通过 ES6 回调执行许多函数 ?

                const f = (funs) => {
                  funs().forEach((fun) => fun)
                }
                
                f(() => [
                  console.log(1),
                  console.log(2),
                  console.log(3)
                ])

                【讨论】:

                  【解决方案16】:

                  在上面我们看到了一些迭代。让我们使用 forEach 做同样的事情:

                  var funcs = [function () {
                          console.log(1)
                    },
                    function () {
                          console.log(2)
                    }
                  ];
                  
                  funcs.forEach(function (func) {
                    func(); // outputs  1, then 2
                  });
                  //for (i = 0; i < funcs.length; i++) funcs[i]();
                  

                  【讨论】:

                  • 最被接受的解决方案基本上是有效的,但尽管实际调用了函数,JS 仍然抛出数组名称不是函数的错误(并在我的可视化中显示该错误)。您的解决方案不会导致该错误。谢谢。
                  【解决方案17】:

                  我在尝试解决这个问题时遇到了很多问题...尝试了显而易见的方法,但没有奏效。它只是以某种方式附加一个空函数。

                  array_of_functions.push(function() { first_function('a string') });
                  

                  我通过使用字符串数组解决了这个问题,后来又使用了 eval:

                  array_of_functions.push("first_function('a string')");
                  
                  for (var Func of array_of_functions) {
                     eval(Func);
                     }
                  

                  【讨论】:

                    【解决方案18】:

                    哎呀,有这么多奇怪的答案......

                    const execute = (fn) => fn()
                    const arrayOfFunctions = [fn1, fn2, fn3]
                    
                    const results = arrayOfFunctions.map(execute)
                    
                    or if you want to sequentially feed each functions result to the next:
                    compose(fn3, fn2, fn1)
                    

                    compose默认是不支持的,但是有像ramda、lodash甚至redux这样的库提供了这个工具

                    【讨论】:

                      【解决方案19】:

                      使用 ES6 语法,如果你需要一个类似“管道”的过程,通过一系列函数(在我的例子中,一个 HTML 抽象语法树)传递同一个对象,你可以使用 for...of 来调用每个管道函数在给定的数组中:

                      const setMainElement = require("./set-main-element.js")
                      const cacheImages = require("./cache-images.js")
                      const removeElements = require("./remove-elements.js")
                      
                      let htmlAst = {}
                      
                      const pipeline = [
                          setMainElement,
                          cacheImages,
                          removeElements,
                          (htmlAst) => {
                              // Using a dynamic closure.
                          },
                      ]
                      
                      for (const pipe of pipeline) {
                          pipe(htmlAst)
                      }
                      

                      【讨论】:

                        【解决方案20】:

                        也许这样可以解决问题:

                        [f1,f2,f3].map((f) =&gt; f('a string'))

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2011-01-16
                          • 2016-08-08
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多