2009-01-30 11 views
47

¿Cómo puedo conectar un evento a un nombre de función que he definido como una cadena?¿Llamar a un nombre de función de JavaScript con una cadena?

Estoy usando Prototype.js, aunque esto no es Prototype-speficic.

$(inputId).observe('click', formData.fields[x].onclick); 

Esto daría como resultado que JavaScript se queje de que mi controlador no es una función. Preferiría que nosotros no usáramos eval().

+0

posible duplicado de [Cómo ejecutar una Función de JavaScript cuando tengo su nombre como una cadena] (http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a- cadena) – olibre

Respuesta

79

Si la función es en el ámbito global, lo puede conseguir mediante el objeto de ventana:

var myFunc = window[myFuncName]; 
+11

... o alcance [myFuncName] en general – annakata

+0

Sí, siempre que tenga un control para el alcance en alguna parte, esto funcionará – Greg

+0

Esto me salvó la vida. Gracias un millón de veces. – Alex

3
window.myFunction === window["myFunction"] 
6

... o esta [myFuncName];

+0

Solución subestimada. Por favor toma mi voto popular. – woodhead92

3

Parece que formData.fields[x].onclick tiene el nombre de una función global? Si es así, intente:

$(inputId).observe('click', window[formData.fields[x].onclick]); 
1

¿Sabe qué contiene la propiedad onclick o qué tipo es? Supongo que esto es un prototipo específico, ya que "fields" no existe en los formularios DOM.

9

He trabajado en este problema, ya que necesitaba una función como esta. Aquí está mi código sandbox, no probado a fondo, pero puede ser un punto de partida para los demás. Tenga en cuenta que hay un eval() en el código, ya que no pude encontrar la manera de omitir ese paso, tal vez una peculiaridad de javascript y no se puede hacer de ninguna otra manera. ¡Avíseme si hay una manera de deshacerse de eval() aquí!

executeFunctionByName = function(functionName) 
{ 
    var args = Array.prototype.slice.call(arguments).splice(1); 
    //debug 
    console.log('args:', args); 

    var namespaces = functionName.split("."); 
    //debug 
    console.log('namespaces:', namespaces); 

    var func = namespaces.pop(); 
    //debug 
    console.log('func:', func); 

    ns = namespaces.join('.'); 
    //debug 
    console.log('namespace:', ns); 

    if(ns == '') 
    { 
     ns = 'window'; 
    } 

    ns = eval(ns); 
    //debug 
    console.log('evaled namespace:', ns); 

    return ns[func].apply(ns, args); 
} 


core = { 
    paragraph: { 
     titlebar: { 
      user: "ddd", 
      getUser: function(name) 
      { 
       this.user = name; 
       return this.user; 
      } 
     } 
    } 
} 

var testf = function() 
{ 
    alert('dkdkdkd'); 
} 

var x = executeFunctionByName('core.paragraph.titlebar.getUser', 'Ikon'); 
executeFunctionByName('testf'); 
+0

Para deshacerse de la evaluación, puede navegar por los espacios de nombres desde el objeto ventana: 'var func = window; for (var i = 0; i

+0

Gracias Ikon. Intenté de muchas maneras, esta respuesta resolverá mi problema. –

5

¿Quizás?

setTimeout ("myFunc()", 1); 
3

Sólo un eval haría el trabajo

var call = eval("method_name").call(args); 
+0

¡Genial! esto funcionó ... gracias; Has olvidado. entre. 'var call = eval (" mathod_name "). Call (args);' – RY35

0

Si necesita llamar a una función de cadena con argumentos, hacer esto:

window[stringFunctionName].apply(window, arrayOfArguments) 

Puede utilizar scope en lugar de window si se prefiere

0

actualización: --- utilizar ES6 exportar e importar

a.js

const fn = { 
    aaa: function() { 
    //code 
    }, 
    bbb: function() { 
    //code 
    }, 
    //codes .... 
    nnn: function() { 
    //code 
    } 
} 

export default fn 

b.js

import someFn from './a' 
    //eg 
    const str1='aaa' 
    const str2 = 'bbb' 

    someFn[str1]() 

Estos métodos anteriores siempre que no sea recomendado en algunas de las razones, pero son muy cómodo de usar. Estos métodos a continuación son seguros, pero realmente no son conveninet para usar.

  • interruptor ... caso (o si otra cosa ...)

    switch(str){ 
        case 'str1': 
         fn1() 
         break 
        case 'str2': 
         fn2 
         //and so on 
    } 
    
  • funciones puestas en un objeto

    const fn={ 
        str1:fn1, 
        str2:fn2 
        //and so on 
    } 
    fn[str1] //call function 
    
+0

¿Cómo responde esto la pregunta? –

Cuestiones relacionadas