Массив функций Javascript


129
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.

Спасибо!


1
Нужно ли 'a string'это знать во время заполнения массива, или может его передать вызывающая функция?
Crescent Fresh

Я хотел бы получить более подробную информацию о том, чего вы пытаетесь достичь, потому что может быть лучший способ справиться с этим.
Джефф

2
«Массив функций» - или, как мы любим называть его, объект с методами
symcbean

Не думаете ли вы, что вам следует сообщить подробности?
IcyFlame

Ответы:


234
var array_of_functions = [
    first_function,
    second_function,
    third_function,
    forth_function
]

а затем, когда вы хотите выполнить заданную функцию в массиве:

array_of_functions[0]('a string');

16
Совет: не забудьте поставить ()после array_of_functions[0], даже если он пуст. Я трачу около 20 минут на то, чтобы понять, «почему это не сработало».
Horacio

Работал как шарм!
Моисей Ндеда

Как получить индекс функции, передав строковое значение, например firstFunction, чтобы оно могло быть динамическим?
О'Дейн Бриссет,

107

Я думаю, что это то, что имел в виду оригинальный плакат:

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-функции в массиве.


3
Это как раз то, что мне было нужно, поскольку это позволяет мне изменять вызовы параметров, предполагая, что все мои функции не принимают одни и те же параметры: P
Джем,

25

Без более подробной информации о том, что вы пытаетесь достичь, мы как бы догадываемся. Но, возможно, вам удастся обойтись без объектной нотации, чтобы сделать что-то вроде этого ...

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

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

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

и позвонить одному из них ...

myFuncs.firstFunc('a string')

1
Я думаю, что это более удобно для разработчиков, поскольку нам не нужно запоминать индекс функции. А также, если мы хотим протолкнуть какую-либо функцию по определенному индексу, это вызывает изменение индекса всех функций рядом с ней. Так что лучше используйте это
dd619

16

Или просто:

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

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

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

13

Я бы дополнил эту тему, опубликовав более простой способ выполнения различных функций в массиве с использованием shift()метода Javascript, первоначально описанного здесь.

  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

Это в основном то же самое, 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]);
}


1
Вы можете добавить свой ответ независимо от количества других. Но предпочтительнее добавить какое-то объяснение, чем он отличается / лучше, чем другие
Bowdzone

3

выше мы видели некоторые с итерацией. Сделаем то же самое с 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]();

1

Это верно

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);

1
Вы уверены, что это тот вопрос, на который вы хотели ответить? Это не связано.
Берги

1
@Bergi На самом деле это так. Заменить Ответим operaс , array_of_functionsи вы получите то же самое. Как насчет сейчас?
Джесси

@Jesse, спасибо, теперь у меня есть идея опубликовать код, это мой первый ответ.
Леонардо Чаччо,

Но у OP был массив, а это какой-то объект (с нечетными названиями свойств)? И какие новости об этом ответе, почему бы просто не проголосовать за pjcabrera или за Робина?
Берги

1
запутанное имя переменной. Это не массив функций, а объект функций
Craicerjack

1

Если вы делаете что-то вроде попытки динамической передачи обратных вызовов, вы можете передать один объект в качестве аргумента. Это дает вам гораздо больший контроль над тем, какие функции вы хотите выполнять с любым параметром.

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


0

Может может кому поможет.

<!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>


0

Проблема с этим массивом функций не в "форме массива", а в том, как эти функции вызываются ... затем ... попробуйте это ... с помощью простого 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 ... (почему я не знаю, но это решило мою проблему)
Quetzal


да, ужасно, как всегда, но выстрел решение, и очень проста в использовании , особенно если его далеко от «входа» ... вот это как раз решить внутреннюю яваскрипта невозможность в короткий путь ...
кетсаль

0

Использование 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')
    ]

0

У меня много проблем, пытаясь решить эту ... попробовал очевидное, но не сработало. Он просто как-то добавляет пустую функцию.

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);
   }

0

Ах, чувак, есть так много странных ответов ...

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, которые предоставляют этот инструмент


-1

у вас есть несколько основных ответов выше. Это просто еще одна версия этого.

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

   FuncTwo: function(string) {
   console.log("second function");
 },

  FuncThree: function(string) {
   console.log("third function");
}

}


2
Вопрос касался массива функций, а не объекта.
trincot

-4
/* 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();
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.