Matriz de funções 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];

Isso não funciona como planejado, porque cada função na matriz é executada quando a matriz é criada.

Qual é a maneira correta de executar qualquer função na matriz, fazendo:

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

Obrigado!

usuario
fonte
1
Será 'a string'necessidade de ser conhecido no momento em que a matriz é preenchida, ou pode o chamador da função passá-lo?
Crescent Fresh
Gostaria de obter mais detalhes sobre o que você está tentando realizar, porque pode haver uma maneira melhor de lidar com isso.
51111 Jeff
2
"Matriz de funções" - ou como gostamos de chamar de objeto com métodos
symcbean
Você não acha que deveria dar mais detalhes? Poderia haver uma maneira melhor de lidar com isso ..
IcyFlame

Respostas:

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

e quando você deseja executar uma determinada função na matriz:

array_of_functions[0]('a string');
Darin Dimitrov
fonte
16
Dica: lembre-se de colocar ()depois array_of_functions[0], mesmo que esteja vazio. Eu gasto 20 minutos apenas para descobrir 'por que isso não funcionou'.
Horacio
Trabalhou como charme!
Moses Ndeda
Como você obteria o índice de uma função passando um valor de string como 'firstFunction' para que ele possa ser dinâmico?
O'Dane Brissett
107

Eu acho que é isso que o pôster original pretendia realizar:

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

Espero que isso ajude outras pessoas (como eu, 20 minutos atrás :-) procurando alguma dica sobre como chamar funções JS em uma matriz.

pjcabrera
fonte
3
Este é apenas o que eu precisava, pois me permite alterar as chamadas de parâmetros, assumindo minhas funções não todos têm os mesmos parâmetros: P
Jem
25

Sem mais detalhes do que você está tentando realizar, estamos meio que supondo. Mas você pode se safar do uso da notação de objeto para fazer algo assim ...

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

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

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

e chamar um deles ...

myFuncs.firstFunc('a string')
Jeff
fonte
1
Eu acho que isso é mais amigável ao desenvolvedor, pois não precisamos nos lembrar do índice de função. E também, se queremos empurrar qualquer função no índice específico, isso causa alteração no índice de todas as funções próximas a ele. Então é melhor usar este
dd619
16

Ou apenas:

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

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

  thirdFunc: function(string) {
    // do something
  }
}
Robin
fonte
13

Eu complementaria esse tópico postando uma maneira mais fácil de executar várias funções dentro de uma matriz usando o shift()método Javascript originalmente descrito aqui

  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();
  }
Gus
fonte
7

É basicamente o mesmo, Darin Dimitrov'smas mostra como você pode usá-lo para criar e armazenar dinamicamente funções e argumentos. Espero que seja útil para você :)

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

Mensur Grišević
fonte
1
É bom adicionar sua resposta, não importa quantas outras existam. Mas é preferível adicionar um pouco de explicação sobre o que é diferente / melhor sobre isso do que os outros
Bowdzone
3

acima, vimos alguns com iteração. Vamos fazer a mesma coisa usando o 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]();
mlhazan
fonte
1

Isto está certo

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);
Leonardo Ciaccio
fonte
1
Tem certeza de que esta é a pergunta que você deseja responder? Não está relacionado.
Bergi 12/05
1
@ Bergi Na verdade, é. Substitua a resposta operapor array_of_functionse você tem a mesma coisa. Que tal agora?
Jesse
@ Jessé obrigado, agora eu tenho uma idéia com postar o código, esta é a minha primeira resposta.
Leonardo Ciaccio
Mas o OP tinha uma matriz, enquanto esse é um objeto (com nomes de propriedades ímpares)? E quais são as notícias desta resposta, por que não apenas votar de pjcabrera ou de Robin?
Bergi 12/05
1
nome confuso da variável. Isso não é uma matriz de funções, mas um objecto de funções
Craicerjack
1

Se você estiver tentando algo como transmitir dinamicamente retornos de chamada, poderá passar um único objeto como argumento. Isso lhe dá um controle muito maior sobre quais funções você deseja executar com qualquer parâmetro.

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
Daniel Lizik
fonte
1

Execução de muitas funções por meio de um retorno de chamada ES6

const f = (funs) => {
  funs().forEach((fun) => fun)
}

f(() => [
  console.log(1),
  console.log(2),
  console.log(3)
])

Thomas Gotwig
fonte
0

Talvez isso possa ajudar alguém.

<!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>
Hopkroft
fonte
0

Uma maneira curta de executar todos:

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

o problema desse conjunto de funções não está na "forma do array", mas na maneira como essas funções são chamadas ... então ... tente isso .. com um simples 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] ); }

funciona aqui, onde nada estava fazendo o trabalho em casa ... espera que ajude

Quetzal
fonte
Você poderia explicar por que outras respostas não funcionam para você e por que as suas funcionam? Obrigado!
Fabio diz Reinstate Monica
ele nunca voltar me erors, função indefinida, ou eles precisly não são evalued por javascript ... (porque eu não sei, mas esta resolveu o meu problema)
Quetzal
1
Terrível conselho. stackoverflow.com/questions/86513/…
Andrei Savin
sim, péssimo, como sempre, mas com solução de tiro e muito fácil de usar, especialmente se estiver longe de ser uma "entrada" ... aqui, apenas resolveu uma impossibilidade interna de javascript de uma maneira curta ...
Quetzal
0

Usando 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')
    ]
YakuZa
fonte
0

Eu tenho muitos problemas tentando resolver este ... tentei o óbvio, mas não funcionou. Apenas acrescenta uma função vazia de alguma forma.

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

Eu o resolvi usando uma matriz de seqüências de caracteres e, posteriormente, com eval:

array_of_functions.push("first_function('a string')");

for (var Func of array_of_functions) {
   eval(Func);
   }
Nezumi
fonte
0

Ah cara, existem tantas respostas estranhas ...

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 não é suportado por padrão, mas existem bibliotecas como ramda, lodash ou mesmo redux que fornecem essa ferramenta

Daniel Tok
fonte
-1

você obteve algumas das principais respostas acima. Esta é apenas outra versão disso.

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

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

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

}

pallimula stackoverflow
fonte
2
A questão era para uma variedade de funções, não um objeto.
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();
user37057
fonte