24

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
  • 756,363
  • 169
  • 1,062
  • 1,111
bobighorus
  • 1,142
  • 4
  • 15
  • 35

6 Answers6

45

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
  • 44,338
  • 13
  • 91
  • 116
  • 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

Create a name -> function map:

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

Then you call the function with:

funcs[number]();
Felix Kling
  • 756,363
  • 169
  • 1,062
  • 1,111
  • 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
7

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,402
  • 15
  • 32
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
  • 53,111
  • 13
  • 85
  • 102
1

As simple as this is:

function hello(){
    alert("hello");
}
var str = "hello";
eval(str+"()");
I.G. Pascual
  • 5,510
  • 5
  • 40
  • 56
  • 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

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,324
  • 12
  • 54
  • 94