Building a function name and executing it

Asked

Viewed 87 times

0

I have an object that is formed by various functions. these functions are table names that from a previous treatment I have to run them. The idea of the code is, if a table does not exist, perform such a function that will create it based on your code.

below follows the function:

//WebSQL connect db
d = openDatabase('test', 'test', 'app', 200 * 1024 * 1024);
db = {
    stage : function(){
        //app tables
        var sys_tables = ['license','config'];
        //verify integrity from database
        d.transaction(function (tx) {
            //sql
            tx.executeSql('SELECT name FROM sqlite_master',[],function(tx, result){
                //catch num rows in select
                var len = result.rows.length, i;
                //for for in sql, search if this val exist in sys_tables
                for (i = 0; i < len; i++){
                    //if not exist, call function to create this table
                    if($.inArray(result.rows.item(i).name , sys_tables) < 0){
                        var table = 'db.make'+result.rows.item(i).name+'()';
                        //>>>>>>>>>>>>HELP HERE<<<<<<<<<<<<
                        console.log(table);
                        //>>>>>>>>>>>>HELP HERE<<<<<<<<<<<<
                    }     
                };
            },null);
        });
    },

    make : {
        //create a license table...
        license : function(){
        //code...
        },
        //create a config table...
        config : function(){
        //code...
        }
    }
}

Does anyone have a solution for that? I’m not being able to think of a way for me to name my functions logically and call them. and I don’t want to make a series of cases, because in this case to each new table I would have to modify this function (unnecessarily reprogramming in my view)...

Some help?

1 answer

1


Accessing object attributes as associative array

Javascript allows you to access attribute values an object through a mechanism similar to -- but not -- to associative arrays:

var db = {
    make: {          // Objeto de interesse (db.make).
        att0: "1",
        att1: "2",
        att2: "3"
    }
};

// Acessando os atributos do objeto de interesse (db.make):
for(var i = 0; i < 3; i++) print(db.make["att" + i]);

// Função de comodidade para imprimir o resultado. Ignore-a :)
function print(source){
    var p = document.createElement("p");
    p.innerHTML = source;
    document.body.appendChild(p);
}

Accessing object attributes-function

Thus, if the attributes of the object in question are functions, to call them just do objeto["prefixo" + indice](), as the next example:

var db = {
    make: {          // Objeto de interesse (db.make).
        mk0: function(){
            print("Criar tabela 1...");
        },
        mk1: function(){
            print("Criar tabela 2...");
        },
        mk2: function(){
            print("Criar tabela 3...");
        }
    }
};

// Acessando os atributos do objeto de interesse (db.make):
for(var i = 0; i < 3; i++) db.make["mk" + i]();

// Função de comodidade para imprimir o resultado. Ignore-a :)
function print(source){
    var p = document.createElement("p");
    p.innerHTML = source;
    document.body.appendChild(p);
}

Non-numerical indices

Our index i is numerical to facilitate the demonstration; however, the index may take any possible way to be converted to string, in order to concatenate properly with the function prefix.

In your case, there are a number of identifiers (Names). Even if they have accents, spaces and punctuation, once the string resulting from the concatenation between the prefix and the key (index) manages to "match" with an object attribute, the corresponding function can be called. Therefore, it is enough to have (or not, as we will see below), for each possible key, a respective function, as the example below:

var chaves = [
    ", mundo",
    ", SO"
];
var obj = {
    "olá, mundo": function(){
        print("Olá, mundo.");
    },
    "olá, SO": function(){
        print("Olá, Stack Overflow em Português!");
    }
};
for(var c in chaves) obj["olá" + chaves[c]]();

// Função de comodidade para imprimir o resultado. Ignore-a :)
function print(source){
    var p = document.createElement("p");
    p.innerHTML = source;
    document.body.appendChild(p);
}

And if the function does not yet exist?

The associative array mechanism allows checking, at runtime, whether a function already exists, before calling it. Better than that: language allows you even declare the function, on the run, if it does not yet exist. With closures, the function can even save values of the declaration moment to your memory:

var chaves = [
    ", mundo",
    ", SO"
];

var obj = {};

for(var c in chaves){
    // Se a função não existir, declara-a, embrulhando sua chave numa closure:
    if(! obj["olá" + chaves[c]]) obj["olá" + chaves[c]] = (function(){
        var thisChave = chaves[c];
        return function(){
            print("Olá" + thisChave + ".");
        };
    })();
    
    // Após isso, podemos chamá-la, na certeza de que existe:
    obj["olá" + chaves[c]]();
}

// Função de comodidade para imprimir o resultado. Ignore-a :)
function print(source){
    var p = document.createElement("p");
    p.innerHTML = source;
    document.body.appendChild(p);
}

Closures are very powerful and can be used in many different ways; with the help of the associative array technique, the possibilities expand; I believe that you can mechanize your function declaration task.

In case of doubt about closures, there’s a lot of material right here at Sopt :)

  • Excellent explanation, thank you very much, certainly helped me pacas!!!

  • 1

    Able, Leandro :) I hope it worked out there, hugging!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.