Масив функцій 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'потрібно знати, коли масив заповнюється, чи може абонент функції передавати його?
Півмісяць свіжий

Мені б хотілося детальніше ознайомитись з тим, що ви намагаєтеся досягти, оскільки може бути кращий спосіб вирішення цього питання.
Джефф

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 хвилин просто, щоб знайти "чому це не вийшло".
Гораціо

Працювали як шарм!
Мойсей Ндеда

Як би ви отримали індекс функції, передавши значення рядка типу "firstFunction", щоб воно могло бути динамічним?
О'Дайн Бріссетт

106

Я думаю, що саме так мав здійснити оригінальний плакат:

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
Jem

24

Без деталізації того, що ви намагаєтеся зробити, ми ніби не здогадуємось. Але ви, можливо, зможете піти, використовуючи позначення об'єктів, щоб зробити щось подібне ...

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 спасибі, тепер у мене є ідея з поштовим кодом, це моя перша відповідь.
Леонардо Ціакціо

Але в ОП був масив, хоча це якийсь об’єкт (з непарними іменами властивостей)? І яка новина цієї відповіді, чому б просто не просити заяву на 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

1

Виконання багатьох функцій за допомогою зворотного дзвінка ES6 🤗

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

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


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


так, жахливо, як ніколи, але знімане рішення, і досить просте у використанні, особливо якщо його далеко не "вхід" ... тут він просто вирішив внутрішню неможливість 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
Питання полягало в масиві функцій, а не в об'єкті.
трінкот

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