Não use a eval
menos que você absolutamente, positivamente , não tenha outra escolha.
Como já foi mencionado, usar algo como isso seria a melhor maneira de fazer isso:
window["functionName"](arguments);
Isso, no entanto, não funcionará com uma função de espaço para nome:
window["My.Namespace.functionName"](arguments); // fail
É assim que você faria isso:
window["My"]["Namespace"]["functionName"](arguments); // succeeds
Para tornar isso mais fácil e fornecer alguma flexibilidade, aqui está uma função de conveniência:
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);
}
Você poderia chamar assim:
executeFunctionByName("My.Namespace.functionName", window, arguments);
Observe que você pode passar no contexto que desejar, para fazer o mesmo que acima:
executeFunctionByName("Namespace.functionName", My, arguments);
My.Namespace.functionName()
,this
fará referência aoMy.Namespace
objeto. Porém, quando você ligaexecuteFunctionByName("My.Namespace.functionName", window)
, não há como sethis
referir à mesma coisa. Talvez ele deva usar o último espaço para nome como escopo ouwindow
se não houver espaços para nome. Ou você pode permitir que o usuário especifique o escopo como argumento.Apenas pensei em publicar uma versão ligeiramente alterada da função muito útil de Jason Bunting .
Primeiro, simplifiquei a primeira instrução fornecendo um segundo parâmetro para slice () . A versão original estava funcionando bem em todos os navegadores, exceto o IE.
Segundo, substituí isso por contexto na declaração de retorno; caso contrário, isso estava sempre apontando para a janela quando a função de destino estava sendo executada.
fonte
A resposta a esta outra pergunta mostra como fazer isso: Javascript equivalente aos locais () do Python?
Basicamente, você pode dizer
ou como muitos outros sugeriram, você pode simplesmente usar eval:
embora isso seja extremamente inseguro, a menos que você esteja absolutamente certo sobre o que está avaliando.
fonte
Você não pode simplesmente fazer isso:
Você também pode executar qualquer outro JavaScript usando esse método.
fonte
eval("My.Namespace.functionName()");
?var codeToExecute = "return My.Namespace.functionName()";
Eu acho que uma maneira elegante de fazer isso é definir suas funções em um objeto hash. Em seguida, você pode ter uma referência a essas funções do hash usando a string por exemplo
Então você pode ligar para:
Onde customFunction será uma sequência que corresponde a uma função definida no seu objeto.
fonte
Com o ES6, você pode acessar os métodos de classe por nome:
a saída seria:
fonte
Object.create()
. const myObj = {method1 () {console.log ('1')}, method2 () {console.log ('2')}} myObj ['method1'] (); // 1 myObj ['method2'] (); // 2Duas coisas:
evitar avaliação, é terrivelmente perigoso e lento
em segundo lugar, não importa onde sua função exista, a integridade "global" é irrelevante.
x.y.foo()
pode ser ativado atravésx.y['foo']()
oux['y']['foo']()
ou mesmowindow['x']['y']['foo']()
. Você pode encadear indefinidamente assim.fonte
Todas as respostas assumem que as funções podem ser acessadas através do escopo global (janela). No entanto, o OP não fez essa suposição.
Se as funções residem em um escopo local (também conhecido como encerramento) e não são referenciadas por outro objeto local, o azar: você precisa usar o
eval()
AFAIK, consulte chamar dinamicamente a função local em javascriptfonte
Você só precisa converter sua string em um ponteiro por
window[<method name>]
. exemplo:e agora você pode usá-lo como um ponteiro.
fonte
Aqui está minha contribuição para as excelentes respostas de Jason Bunting / Alex Nazarov, onde incluo a verificação de erros solicitada por Crashalot.
Dado este preâmbulo (artificial):
então a seguinte função:
permitirá que você chame uma função javascript pelo nome armazenado em uma string, com espaço para nome ou global, com ou sem argumentos (incluindo objetos Array), fornecendo feedback sobre os erros encontrados (esperançosamente detectados).
A saída de amostra mostra como funciona:
fonte
if( typeof context[ functionName ] !== 'function' )
porque o contexto - janela - é definido, é um objeto e uma matriz, mas a janela ['abcd'] não existe, pois foi identificada como um problema no sistema aceito resposta:window["My.Namespace.functionName"](arguments); // fail
Dependendo de onde você está, você também pode usar:
ou, em nodejs
fonte
Se você deseja chamar uma função de um objeto em vez de uma função global com
window["functionName"]
. Você pode fazer isso como;Exemplo:
fonte
SEJA CUIDADOSO!!!
Deve-se tentar evitar chamar uma função por string no JavaScript por dois motivos:
Razão 1: alguns ofuscadores de código danificam seu código, pois alteram os nomes das funções, tornando a string inválida.
Razão 2: É muito mais difícil manter o código que usa essa metodologia, pois é muito mais difícil localizar usos dos métodos chamados por uma string.
fonte
Aqui está minha abordagem Es6, que permite que você chame sua função pelo nome como string ou nome da função e também permita que você passe diferentes números de argumentos para diferentes tipos de funções:
fonte
Surpreendeu-me ao ver nenhuma menção de setTimeout.
Para executar uma função sem argumentos:
Para executar a função com argumentos:
Para executar uma função profundamente espaçada no nome:
fonte
runMe
com alguns argumentos.Então, como outros disseram, definitivamente a melhor opção é:
E, como Jason Bunting disse , não funcionará se o nome da sua função incluir um objeto:
Então, aqui está minha versão de uma função que executará todas as funções por nome (incluindo um objeto ou não):
fonte
Uma solução mais OOP ...
fonte
Mais um detalhe nas postagens de Jason e Alex. Achei útil adicionar um valor padrão ao contexto. Basta colocar
context = context == undefined? window:context;
no início da função. Você pode mudarwindow
para qualquer que seja o seu contexto preferido e não precisará passar a mesma variável sempre que chamar isso em seu contexto padrão.fonte
Para adicionar à resposta de Jason Bunting, se você estiver usando nodejs ou algo assim (e isso também funciona em dom js), você pode usar em
this
vez dewindow
(e lembre-se: eval is evil :fonte
Há uma coisa muito semelhante no meu código. Eu tenho uma string gerada pelo servidor que contém um nome de função que eu preciso passar como retorno de chamada para uma biblioteca de terceiros. Então, eu tenho um código que pega a string e retorna um "ponteiro" para a função, ou null se não for encontrado.
Minha solução foi muito semelhante à " função muito útil de Jason Bunting " * , embora não seja executada automaticamente e o contexto esteja sempre na janela. Mas isso pode ser facilmente modificado.
Espero que isso seja útil para alguém.
fonte
Há também alguma maneira muito útil.
http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
fonte
Não consigo resistir a mencionar outro truque, que ajuda se você tiver um número desconhecido de argumentos que também estão sendo passados como parte da string que contém o nome da função. Por exemplo:
var annoyingstring = 'call_my_func(123, true, "blah")';
Se o seu Javascript estiver sendo executado em uma página HTML, tudo o que você precisa é de um link invisível; você pode passar uma string para o
onclick
atributo e chamar oclick
método<a href="#" id="link_secret"><!-- invisible --></a>
Ou crie o
<a>
elemento em tempo de execução.fonte
A maneira mais fácil é acessá-lo como tem o elemento
é o mesmo que
fonte
Você pode chamar a função javascript dentro de
eval("functionname as string")
qualquer um. Como abaixo: (eval é pura função javascript)Exemplo de trabalho: https://jsfiddle.net/suatatan/24ms0fna/4/
fonte
Isso está funcionando para mim:
Eu espero que isso funcione.
fonte
Eu não acho que você precise de funções intermediárias complicadas ou eval ou seja dependente de variáveis globais como window:
Também funcionará com funções importadas:
fonte
Sem usar,
eval('function()')
você pode criar uma nova função usandonew Function(strName)
. O código abaixo foi testado usando FF, Chrome, IE.fonte
fonte
Parece básico:
Existe outro tipo de função é class e look example nils petersohn
fonte
Obrigado pela resposta muito útil. Estou usando a função de Jason Bunting em meus projetos.
Eu o estendi para usá-lo com um tempo limite opcional, porque a maneira normal de definir um tempo limite não funcionará. Ver a pergunta de abhishekisnot
fonte