No lo use a eval
menos que absolutamente, positivamente no tenga otra opción.
Como se ha mencionado, usar algo como esto sería la mejor manera de hacerlo:
window["functionName"](arguments);
Sin embargo, eso no funcionará con una función de espacio de nombres:
window["My.Namespace.functionName"](arguments); // fail
Así es como lo harías:
window["My"]["Namespace"]["functionName"](arguments); // succeeds
Para facilitarlo y proporcionar cierta flexibilidad, aquí hay una función de conveniencia:
function executeFunctionByName(functionName, context /*, args */) {
var args = Array.prototype.slice.call(arguments, 2);
var namespaces = functionName.split(".");
var func = namespaces.pop();
for(var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
return context[func].apply(context, args);
}
Lo llamarías así:
executeFunctionByName("My.Namespace.functionName", window, arguments);
Tenga en cuenta que puede pasar en el contexto que desee, por lo que esto haría lo mismo que arriba:
executeFunctionByName("Namespace.functionName", My, arguments);
My.Namespace.functionName()
,this
se referirá alMy.Namespace
objeto. Pero cuando llamaexecuteFunctionByName("My.Namespace.functionName", window)
, no hay formathis
de referirse a lo mismo. Tal vez debería usar el último espacio de nombres como el alcance, owindow
si no hay espacios de nombres. O podría permitir que el usuario especifique el alcance como argumento.Solo pensé en publicar una versión ligeramente alterada de la función muy útil de Jason Bunting .
Primero, he simplificado la primera declaración al proporcionar un segundo parámetro para cortar () . La versión original funcionaba bien en todos los navegadores, excepto IE.
En segundo lugar, he reemplazado esto con contexto en la declaración de devolución; de lo contrario, esto siempre apuntaba a la ventana cuando se ejecutaba la función de destino.
fuente
La respuesta a esta otra pregunta le muestra cómo hacerlo: ¿ Javascript equivalente a los locales de Python ()?
Básicamente, puedes decir
o como muchos otros han sugerido, puede usar eval:
aunque esto es extremadamente inseguro a menos que esté absolutamente seguro de lo que está evaluando.
fuente
¿No podrías simplemente hacer esto?
También puede ejecutar cualquier otro JavaScript utilizando este método.
fuente
eval("My.Namespace.functionName()");
?var codeToExecute = "return My.Namespace.functionName()";
Creo que una forma elegante de hacerlo es definiendo sus funciones en un objeto hash. Entonces puede tener una referencia a esas funciones desde el hash usando la cadena. p.ej
Entonces puedes llamar:
Donde customFunction será una cadena que coincida con una función definida en su objeto.
fuente
Con ES6 puede acceder a los métodos de clase por nombre:
la salida sería:
fuente
Object.create()
. const myObj = {method1 () {console.log ('1')}, method2 () {console.log ('2')}} myObj ['method1'] (); // 1 myObj ['método2'] (); // 2Dos cosas:
evite evaluar, es terriblemente peligroso y lento
en segundo lugar, no importa dónde exista su función, la "globalidad" es irrelevante.
x.y.foo()
puede ser activado a travésx.y['foo']()
ox['y']['foo']()
ni siquierawindow['x']['y']['foo']()
. Puedes encadenar indefinidamente de esta manera.fuente
Todas las respuestas suponen que se puede acceder a las funciones a través del alcance global (ventana). Sin embargo, el OP no hizo esta suposición.
Si las funciones viven en un ámbito local (también conocido como cierre) y no están referenciadas por algún otro objeto local, mala suerte: debe usar
eval()
AFAIK, vea llamar dinámicamente a la función local en javascriptfuente
Solo necesita convertir su cadena en un puntero por
window[<method name>]
. ejemplo:y ahora puedes usarlo como un puntero.
fuente
Aquí está mi contribución a las excelentes respuestas de Jason Bunting / Alex Nazarov, donde incluyo la verificación de errores solicitada por Crashalot.
Dado este preámbulo (artificial):
entonces la siguiente función:
le permitirá llamar a una función de JavaScript por el nombre almacenado en una cadena, ya sea de espacios de nombres o global, con o sin argumentos (incluidos los objetos de matriz), proporcionando comentarios sobre los errores encontrados (con suerte, atrapándolos).
La salida de muestra muestra cómo funciona:
fuente
if( typeof context[ functionName ] !== 'function' )
porque el contexto - ventana - está definido, es un objeto y una matriz, pero la ventana ['abcd'] no existe como se identificó como un problema en el aceptado respuesta:window["My.Namespace.functionName"](arguments); // fail
Dependiendo de dónde se encuentre, también puede usar:
o, en nodejs
fuente
Si desea llamar a una función de un objeto en lugar de una función global con
window["functionName"]
. Puedes hacerlo como;Ejemplo:
fuente
¡¡¡TEN CUIDADO!!!
Uno debe tratar de evitar llamar a una función por cadena en JavaScript por dos razones:
Razón 1: Algunos ofuscadores de código destruirán su código ya que cambiarán los nombres de las funciones, lo que invalidará la cadena.
Razón 2: es mucho más difícil mantener el código que utiliza esta metodología, ya que es mucho más difícil localizar el uso de los métodos llamados por una cadena.
fuente
Aquí está mi enfoque Es6 que le permite llamar a su función por su nombre como cadena o su nombre de función y también le permite pasar diferentes números de argumentos a diferentes tipos de funciones:
fuente
Sorprendido de no ver mención de setTimeout.
Para ejecutar una función sin argumentos:
Para ejecutar la función con argumentos:
Para ejecutar una función de espacios de nombres profundos:
fuente
runMe
con algunos argumentos.Entonces, como otros dijeron, definitivamente la mejor opción es:
Y como dijo Jason Bunting , no funcionará si el nombre de su función incluye un objeto:
Así que aquí está mi versión de una función que ejecutará todas las funciones por nombre (incluido un objeto o no):
fuente
Una solución más OOP ...
fuente
Un detalle más sobre las publicaciones de Jason y Alex. Me pareció útil agregar un valor predeterminado al contexto. Solo ponlo
context = context == undefined? window:context;
al comienzo de la función. Puede cambiarwindow
a su contexto preferido, y luego no necesitará pasar la misma variable cada vez que llame a esto en su contexto predeterminado.fuente
Para agregar a la respuesta de Jason Bunting, si está usando nodejs o algo (y esto también funciona en dom js), puede usar en
this
lugar dewindow
(y recuerde: eval es malo :fuente
Hay algo muy similar en mi código. Tengo una cadena generada por el servidor que contiene un nombre de función que necesito pasar como devolución de llamada para una biblioteca de terceros. Entonces tengo un código que toma la cadena y devuelve un "puntero" a la función, o nulo si no se encuentra.
Mi solución fue muy similar a la " función muy útil de Jason Bunting " * , aunque no se ejecuta automáticamente, y el contexto siempre está en la ventana. Pero esto se puede modificar fácilmente.
Esperemos que esto sea útil para alguien.
fuente
También hay alguna forma muy útil.
http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
fuente
No puedo resistirme a mencionar otro truco, que ayuda si tienes un número desconocido de argumentos que también se pasan como parte de la cadena que contiene el nombre de la función. Por ejemplo:
var annoyingstring = 'call_my_func(123, true, "blah")';
Si su Javascript se ejecuta en una página HTML, todo lo que necesita es un enlace invisible; puede pasar una cadena al
onclick
atributo y llamar alclick
método.<a href="#" id="link_secret"><!-- invisible --></a>
O cree el
<a>
elemento en tiempo de ejecución.fuente
La forma más fácil es acceder a ella como si tuviera un elemento
es igual que
fuente
Puede llamar a la función javascript dentro de
eval("functionname as string")
cualquiera. Como a continuación: (eval es pura función de javascript)Ejemplo de trabajo: https://jsfiddle.net/suatatan/24ms0fna/4/
fuente
Esto es trabajo para mí:
Espero que esto funcione.
fuente
No creo que necesite funciones intermedias complicadas o eval o dependa de variables globales como window:
También funcionará con funciones importadas:
fuente
Sin usar
eval('function()')
, podría crear una nueva función usandonew Function(strName)
. El siguiente código se probó con FF, Chrome, IE.fuente
fuente
Mira básico:
Existe otro tipo de función es class y mira el ejemplo nils petersohn
fuente
Gracias por la respuesta muy útil. Estoy usando la función de Jason Bunting en mis proyectos.
Lo extendí para usarlo con un tiempo de espera opcional, porque la forma normal de establecer un tiempo de espera no funcionará. Ver la pregunta de abhishekisnot
fuente