Javascript Array of Functions


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

ฉันต้องการทราบรายละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่คุณพยายามทำเพราะอาจมีวิธีจัดการที่ดีกว่านี้
Jeff

2
"Array of Functions" หรือที่เราชอบเรียกว่าวัตถุด้วยวิธีการ
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

ทำงานอย่างมีเสน่ห์!
Moses Ndeda

คุณจะได้รับดัชนีของฟังก์ชันอย่างไรโดยการส่งผ่านค่าสตริงเช่น 'firstFunction' เพื่อให้เป็นแบบไดนามิกได้
O'Dane Brissett

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
Jem

25

หากไม่มีรายละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่คุณกำลังพยายามทำให้สำเร็จเราคาดเดาได้ แต่คุณอาจหลีกหนีจากการใช้สัญกรณ์วัตถุเพื่อทำสิ่งนี้ได้ ...

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

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

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

และเรียกหนึ่งในนั้น ...

myFuncs.firstFunc('a string')

1
ฉันคิดว่านี่เป็นมิตรกับนักพัฒนามากกว่าเนื่องจากเราไม่จำเป็นต้องจำดัชนีของฟังก์ชัน และถ้าเราต้องการพุชฟังก์ชันใด ๆ ที่ดัชนีเฉพาะก็จะทำให้เกิดการเปลี่ยนแปลงดัชนีของฟังก์ชันทั้งหมดที่อยู่ข้างๆ ใช้สิ่งนี้ดีกว่า
dd619


13

ฉันจะเสริมเธรดนี้ด้วยการโพสต์วิธีที่ง่ายกว่าในการเรียกใช้ฟังก์ชันต่างๆภายใน Array โดยใช้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
แน่ใจหรือว่านี่คือคำถามที่คุณต้องการคำตอบ มันไม่เกี่ยวกัน
Bergi

1
@Bergi ที่จริงมันเป็น. แทนที่คำตอบoperaด้วยarray_of_functionsและคุณมีสิ่งเดียวกัน แล้วตอนนี้ล่ะ?
Jesse

@Jesse ขอบคุณตอนนี้ฉันมีความคิดที่จะโพสต์รหัสนี่เป็นการตอบกลับครั้งแรกของฉัน
Leonardo Ciaccio

แต่ OP มีอาร์เรย์ในขณะที่นี่คือวัตถุบางอย่าง (มีชื่อคุณสมบัติแปลก ๆ )? และข่าวของคำตอบนี้คืออะไรทำไมไม่เพียงแค่โหวตให้คะแนน pjcabrera หรือโรบิน?
Bergi

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

วิธีสั้น ๆ ในการเรียกใช้พวกเขาทั้งหมด:

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

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

มันทำงานที่นี่โดยที่ไม่มีอะไรอยู่บนบ้านได้ ... หวังว่ามันจะช่วยได้


คุณช่วยอธิบายได้ไหมว่าทำไมคำตอบอื่น ๆ ถึงไม่เหมาะกับคุณและทำไมคำตอบของคุณถึงตอบ ขอบคุณ!
Fabio กล่าว Reinstate Monica

มันเคยส่งคืนฉันผิดพลาดฟังก์ชันที่ไม่ได้กำหนดหรือพวกเขาไม่ได้รับการประเมินโดยจาวาสคริปต์อย่างชัดเจน ... (ทำไมฉันไม่รู้ แต่สิ่งนี้ช่วยแก้ปัญหาของฉันได้)
Quetzal

1
คำแนะนำแย่มาก stackoverflow.com/questions/86513/…
Andrei Savin

ใช่แย่มากเช่นเคย แต่วิธีแก้ปัญหาการยิงและค่อนข้างใช้งานง่ายโดยเฉพาะอย่างยิ่งหากอยู่ไกลจาก "อินพุต" ... ที่นี่มันเพิ่งแก้ไขความเป็นไปไม่ได้ของจาวาสคริปต์ภายในในระยะสั้น ๆ ...
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();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.