Calling one function within the other, via a string

To facilitate the work of the other programmers of the company whose default is not to have default, I created a JavaScript library with some functions of formatting and validation of form fields (date, phone, CPF, CNPJ, etc.).

At the end of the process, this library allowed me a very simple call:

<input type="[data|telefone|...]" name="" value="">

At the end of page loading I generate a NodeList and assign the proper functions for each input accordingly with your type.

Such code then got like this: JSBin.com

The problem with the method used is that although only one of the functions is being executed for each input (as it should be), I am setting all functions for each object found in my NodeList. That is, for each object I get a kilometer code, containing several functions that this object will never use .

On pages normal, where this feature is not widely used, the problem is completely imperceptible. However, on pages where these functions are called numerous times, it is possible to notice a certain loss of performance after loading the page.
And, since the company's system is to be used also on mobile devices, a small loss of performance can end up becoming a big problem.

To work around this, I thought of isolating each of the functions. Here's mine problem!
I have N functions ( date, phone, cpf,...), inside a global function (setEvents ) and all I have to call these inner functions is their name in the form of string.

I have tried several ways, but have not succeeded.
The only way that worked so far was by using eval. But as the JS Bin says: "eval is evil."

Author: Sergio, 2014-03-31

4 answers

Just a suggestion, you can put the functions inside an object, and call the same by name:

<script>
  function a() {
    var nomeDaFuncao = [função a ser chamada];

    var fncObj = {
        b: function(objeto) {
         . . .
        }

        c: function(objeto) {
         . . .
        }
    }

    fncObj[nomeDaFuncao](objeto);
  }
</script>

But it would be much better if you explain the reason for this strange logic... because even the way I said it, it sounds kind of weird to me to have something like that... would a switch not solve?

 5
Author: Miguel Angelo, 2014-03-31 19:50:29

Hello, try to do like this:

function a(){
    alert('olá a');
    var nomeFuncao = 'b';
    var b = function(){
        alert('olá b');
    };

    var c = function(){
        alert('olá c');
    };

    eval(nomeFuncao)();
}

JS Bin

You can also use this alternative without eval():

func_a = function(arg1) {
    alert('call a '+ arg1);
};
func_b = function() {
    alert('b');
};
func_c = function() {
    alert('c');
};

var n = "a";

 window["func_" + n]('arg1');

Js Fiddle

Another option using Jquery:

$.main = {
    a : function(arg){
        alert('function a - arg: '+arg);
    },
    b : function(){
        alert('b');
    },
    c : function(){
        alert('c');
    },
    call : function(func,arg){
        $.main[func](arg);
    }
};
$.main.call('a','param 1');
$.main.call('b');
$.main.call('c');

With JQuery

 3
Author: abfurlan, 2014-04-01 17:53:37

You can use a namespace for this. An object with multiple functions where it calls the function it needs and does not pollute the global space as in its original idea.

var validar = {

    date: function (value) {
        return [value, 'Função para data'];
    },
    text: function (value) {
        return [value, 'Função para texto'];
    },
    password: function (value) {
        return [value, 'Função para passwords'];
    }
}

And then you can use like this:

// "el" no exemplo é o elemento que quer analisar
var type = el.getAttribute("type");
var retornoFuncao = validar[type](el.value);

Example

I used the same code within each function but I imagine I wanted to adapt that part.

 2
Author: Sergio, 2014-04-01 04:21:21

Try adding your functions explicitly in the window object as HERE :

window.dyna = function(param) {
    alert("dyna " + param);
}
window["dyna"]("oi");

Some browsers this isn't even necessary and would work the way you did.

Edit 1

Testing here does not work in your example because the functions b() and c() are not directly in the object window. Thus they are not found in the scope of window

Since they are created in the scope of function a(), and they will only exist inside function a(), and if inside a() you want to access b(), for example, you have to do something like this:

this["b"]();
// que é o mesmo que this.b();

Edit 2

To use the this, as I mentioned you have to do something like this, your problem is scoped, so you have to attach your function to an object that is accessible in the scope where you intend to call it, in the case of the this, as follows in the example code:

function a(nomeDaFuncao) {

  // anexa a function "b" ao objeto local this
  this.b  = function(param) {
      alert("b " + param);
  }

  // anexa a function "c" ao objeto local this
  this.c = function(param) {
      alert("c " + param);
  }

  // chama a function pelo nome no objeto local this
  this[nomeDaFuncao]("oi");
}

a(nomeDaFuncao);

Example here

For understand a little better how the scope of objects in javascript works, I recommend this link which is very good and this from MDN.

Note: I don't know what your real problem is to need such a solution, more depending on which one, there may be simpler and cleaner ways to do, more this solution will work for your current question.

 1
Author: Fernando Leal, 2014-04-01 02:31:57