25

I have several jQuery function like function setOne(); setTwo(); setThree();

and a variable var number that values respectively "one", "two", "three".

How can I call function "setOne()" when number values "one", function "setTwo" when number values "two" and so on...?

Thank you so much in advance. Any help will be apreciated.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
bobighorus
  • 1,152
  • 4
  • 17
  • 35

7 Answers7

47

If you have your function in the global scope (on the window object) you can do:

// calls function setOne, setTwo, ... depending on number.
window["set" + number](); 

And using eval will allow you to run functions in local scope:

eval("set" + number + "()");

When is JavaScript's eval() not evil?

Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
  • Best answer, I accept this, simple and helpful and you know exactly what I mean! Thank you! If you you want you can vote my question. – bobighorus Dec 21 '11 at 10:39
  • `this["set" + number]();` would not work. Only if `setX` is a property of whatever `this` refers to, but not if `setX` is a local variable. – Felix Kling Dec 21 '11 at 10:43
  • 1
    Sorry, but if `number` is exactly as bobighorus describes (e.g. `one`, `two`, `three`) then this will give an error, as `setone` != `setOne`?! – Yoshi Dec 21 '11 at 10:55
  • @AndreasAL Ah, thanks! ;) Then why not copy that part from my answer so we'll have it in the accepted answer too :) – Yoshi Dec 21 '11 at 11:02
  • Great ! Congratulations – w3spi Nov 29 '21 at 07:31
8

If the variable details the actual name of the JQuery function and you want to apply the function to a DOM element like 'body', you can do the following:

 $('body')['function-name']('params');
Hozeis
  • 1,542
  • 15
  • 36
8

Create a name -> function map:

var funcs = {
    'one': setOne,
    'two': setTwo
    /*...*/
};

Then you call the function with:

funcs[number]();
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Actually AndreasAL's answer is the better one. People need to understand that in JavaScript everything is a dictionary and even functions are only entries on the global scope dictionary that you can access in that way. – Tigraine Dec 21 '11 at 10:33
  • Thanks for your answer Felix, but it seems like a switch iteration. I need an automatic solution like set+number+() that means setOne(); . I hope I was clear. – bobighorus Dec 21 '11 at 10:34
  • @Tigraine: It only works if the functions are global which in general is not a good idea (global namespace pollution). – Felix Kling Dec 21 '11 at 10:37
  • @bobighorus: Well, you can also assign the functions directly to the object instead of defining them beforehand. Whether you do `function setOne() {...};` or `funcs['one'] = function() {...};` should not make a big difference. The advantage is that your code has a cleaner structure and is easier to understand. – Felix Kling Dec 21 '11 at 10:39
  • @Felix Kling: You can still declare the functions on a deeper scope and use the this[] notation as AndreasAL suggested.. – Tigraine Dec 21 '11 at 10:41
  • @Tigraine: That won't work. Only in global scope `this` refers to `window`, but you can never access local variables through `this`. – Felix Kling Dec 21 '11 at 10:42
  • @Felix Kling: You can simply do so by setting this through `.call` but you get into trouble as `function ()` are only seen as local variables inside functions.. Best I could come up is similar to your approach: http://jsfiddle.net/85YSX/ – Tigraine Dec 21 '11 at 10:58
2

Provided your functions are in the global scope, try:

function setOne() {
  console.log('setOne called');
}
function setTwo() {
  console.log('setTwo called');
}
function setThree() {
  console.log('setThree called');
}

var number, funcName;

number = 'one';
funcName = 'set' + number.charAt(0).toUpperCase() + number.slice(1);
window[funcName](); // output: setOne called

number = 'two';
funcName = 'set' + number.charAt(0).toUpperCase() + number.slice(1);
window[funcName](); // output: setTwo called

number = 'three';
funcName = 'set' + number.charAt(0).toUpperCase() + number.slice(1);
window[funcName](); // output: setThree called
Yoshi
  • 54,081
  • 14
  • 89
  • 103
1

As simple as this is:

function hello(){
    alert("hello");
}
var str = "hello";
eval(str+"()");
I.G. Pascual
  • 5,818
  • 5
  • 42
  • 58
  • Yeah but I have to call a function! – bobighorus Dec 21 '11 at 10:40
  • 1
    @bobighorus This calls the function hello()... use `var str = "One";` `eval("set" + str + "()");` for your example. You can even set *named parameters* this way... `eval("set" + str + "(parameterName)");` – I.G. Pascual Dec 21 '11 at 10:52
0

Further to @Andreas answer, the following illustrates the approach when not using a global.

Make a variable that holds a set of functions:

var callbacks = {
    setOne: function(params) {
        // ...
    },
    setTwo: function(params) {
        // ...
    },
};

Then if you have a variable holding the function name, you can do:

var number = "Two";
callbacks["set" + number](params);
aberdat
  • 791
  • 5
  • 5
0

Why do you have three functions for that?

var number;
function setNumber(n) {
    number = n;
}

setNumber(1) will set number to 1

setNumber(2) will set number to 2

ect

OptimusCrime
  • 14,662
  • 13
  • 58
  • 96