Tablica funkcji 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];

To nie działa zgodnie z przeznaczeniem, ponieważ każda funkcja w tablicy jest wykonywana podczas tworzenia tablicy.

Jaki jest właściwy sposób wykonania dowolnej funkcji w tablicy, wykonując:

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

Dzięki!

Nacięcie
źródło
1
Czy 'a string'musi być znana w momencie zapełniania tablicy, czy też obiekt wywołujący funkcję może ją przekazać?
Crescent Fresh
Chciałbym uzyskać więcej szczegółów na temat tego, co próbujesz osiągnąć, ponieważ może być lepszy sposób na rozwiązanie tego problemu.
Jeff,
2
„Tablica funkcji” - lub jak lubimy nazywać to obiektem z metodami
symcbean
Nie sądzisz, że powinieneś podać więcej szczegółów? Mógłby być lepszy sposób na
poradzenie

Odpowiedzi:

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

a potem kiedy chcesz wykonać daną funkcję w tablicy:

array_of_functions[0]('a string');
Darin Dimitrov
źródło
16
Wskazówka: Pamiętaj, aby umieścić ()po array_of_functions[0], nawet jeśli jest pusty. Spędzam około 20 minut, aby dowiedzieć się, dlaczego to nie zadziałało.
Horacio,
Działało jak urok!
Moses Ndeda
Jak uzyskać indeks funkcji, przekazując wartość ciągu, taką jak „firstFunction”, aby mogła być dynamiczna?
O'Dane Brissett
106

Myślę, że to właśnie miał na celu oryginalny plakat:

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

Miejmy nadzieję, że pomoże to innym (jak ja 20 minut temu :-), szukającym jakiejkolwiek wskazówki, jak wywoływać funkcje JS w tablicy.

pjcabrera
źródło
3
To jest właśnie to, czego potrzebowałem, ponieważ pozwala mi zmienić wywołania parametrów, zakładając, że moje funkcje nie przyjmują tych samych parametrów: P
Jem
24

Bez większej ilości szczegółów tego, co próbujesz osiągnąć, trochę zgadujemy. Ale możesz być w stanie uciec z użyciem notacji obiektowej, aby zrobić coś takiego ...

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

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

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

i zadzwonić do jednego z nich ...

myFuncs.firstFunc('a string')
Jeff
źródło
1
Myślę, że jest to bardziej przyjazne dla programistów, ponieważ nie musimy pamiętać indeksu funkcji. A także, jeśli chcemy wypchnąć jakąkolwiek funkcję do określonego indeksu, powoduje to zmianę indeksu wszystkich funkcji obok niej. Więc lepiej użyj tego
dd619
16

Lub tylko:

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

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

  thirdFunc: function(string) {
    // do something
  }
}
Rudzik
źródło
13

Uzupełniłbym ten wątek, zamieszczając łatwiejszy sposób wykonywania różnych funkcji w tablicy przy użyciu shift()metody JavaScript pierwotnie opisanej tutaj

  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
źródło
7

Zasadniczo jest to to samo, co, Darin Dimitrov'sale pokazuje, jak można go używać do dynamicznego tworzenia i przechowywania funkcji i argumentów. Mam nadzieję, że Ci się przyda :)

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ć
źródło
1
Dobrze jest dodać swoją odpowiedź bez względu na to, ile jest innych. Ale lepiej jest dodać jakieś wyjaśnienie, co jest w tym inne / lepsze niż w innych
Bowdzone
3

powyżej widzieliśmy niektóre z iteracjami. Zróbmy to samo, używając 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
źródło
1

To jest poprawne

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
źródło
1
Czy na pewno jest to pytanie, na które chciałeś odpowiedzieć? To nie jest powiązane.
Bergi
1
@Bergi Właściwie to jest. Wymień słyszą odpowiedź operaz array_of_functionsi masz to samo. A teraz?
Jesse
@Jesse dzięki, teraz mam pomysł z wysłaniem kodu, to moja pierwsza odpowiedź.
Leonardo Ciaccio
Ale OP miał tablicę, podczas gdy to jest jakiś obiekt (z dziwnymi nazwami właściwości)? A jakie są wiadomości z tej odpowiedzi, dlaczego nie po prostu głosować za pjcabrera lub Robin?
Bergi
1
myląca nazwa zmiennej. To nie jest tablica funkcji, ale obiekt funkcji
Craicerjack
1

Jeśli robisz coś takiego, jak próba dynamicznego przekazywania wywołań zwrotnych, możesz przekazać pojedynczy obiekt jako argument. Daje to znacznie większą kontrolę nad funkcjami, które chcesz wykonywać z dowolnym parametrem.

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
źródło
1

Wykonywanie wielu funkcji poprzez wywołanie zwrotne ES6 🤗

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

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

Thomas Gotwig
źródło
0

Może to komuś pomoże.

<!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
źródło
0

Krótki sposób, aby je wszystkie uruchomić:

[first_function, ..., nth_function].forEach (function(f) {
    f('a string');
}); 
Danyal Aytekin
źródło
0

problem z tymi tablicami funkcji nie ma "postaci tablicowej", ale w sposobie, w jaki te funkcje są nazywane ... wtedy ... spróbuj tego ... z prostym 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] ); }

to działa tutaj, gdzie nic górnego nie wykonywało pracy w domu ... mam nadzieję, że to pomoże

Quetzal
źródło
Czy możesz wyjaśnić, dlaczego inne odpowiedzi nie działają w Twoim przypadku i dlaczego tak jest? Dziękuję Ci!
Fabio mówi Reinstate Monica
zawsze zwraca mi błędy, niezdefiniowaną funkcję lub nie są one precyzyjnie oceniane przez javascript ... (dlaczego nie wiem, ale to rozwiązało mój problem)
Quetzal
1
Okropna rada. stackoverflow.com/questions/86513/…
Andrei Savin
tak, okropne, jak zawsze, ale rozwiązanie strzałowe i całkiem łatwe w użyciu, zwłaszcza jeśli jest dalekie od "wejścia" ... tutaj właśnie rozwiązało wewnętrzną niemożliwość javascript w skrócie ...
Quetzal
0

Korzystanie z funkcji 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
źródło
0

Mam wiele problemów, próbując rozwiązać ten problem ... wypróbowałem oczywiste, ale nie zadziałało. W jakiś sposób dodaje pustą funkcję.

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

Rozwiązałem to używając tablicy ciągów, a później z eval:

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

for (var Func of array_of_functions) {
   eval(Func);
   }
Nezumi
źródło
0

Człowieku, jest tyle dziwnych odpowiedzi ...

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 nie jest domyślnie obsługiwany, ale istnieją biblioteki, takie jak ramda, lodash, a nawet redux, które zapewniają to narzędzie

Daniel Tok
źródło
-1

masz kilka najlepszych odpowiedzi powyżej. To tylko kolejna wersja tego.

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
źródło
2
Pytanie dotyczyło tablicy funkcji, a nie obiektu.
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
źródło