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!


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

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.


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

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

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

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


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

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

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

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


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>

0

Uma maneira curta de executar todos:

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

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


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


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')
    ]

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

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


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

}


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();
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.