Quando eu estava implementando o mecanismo JScript, eu defendia a impressão de camisas EVAL IS EVIL , mas, infelizmente, nunca chegamos a isso.
Meu maior problema com a avaliação não é o óbvio ataque malicioso de injeção de código, embora isso certamente seja uma preocupação enorme. Meu maior problema é que as pessoas tendem a usá-lo como um martelo realmente grande para resolver problemas realmente pequenos. A maioria dos usos do mundo real que eu vi de "eval" na natureza quando eu estava na equipe do JScript poderia ter sido resolvida trivialmente usando uma tabela de pesquisa; e como todo objeto no JScript já é uma tabela de pesquisa , não é como se isso fosse um fardo oneroso. O Eval inicia o compilador novamente e destrói completamente a capacidade do compilador de otimizar seu código .
Para mais algumas reflexões nesse sentido, veja meus artigos de 2003 sobre o assunto:
Maldade geral:
http://blogs.msdn.com/b/ericlippert/archive/2003/11/01/53329.aspx
Ataque do ataque por injeção:
http://blogs.msdn.com/b/ericlippert/archive/2003/11/04/53335.aspx
eval
grandes pedaços de código da maneira que aplicativos como o JSPacker gostam? O JSPacker + gzip geralmente resulta em tamanhos de arquivo menores do que qualquer solução por si só, mas como você corretamente aponta, ele essencialmente está disparando um compilador duas vezes no mesmo pedaço de código, além de algumas despesas gerais para fazer substituições de cadeias.eval()
é não um risco de segurança em código de cliente (browser).A maioria das falhas de segurança é do mesmo tipo que na injeção SQL, concatenando a entrada do usuário no código JavaScript. A diferença é que, embora haja maneiras de garantir que isso não aconteça com o SQL, não há muito o que fazer com JavaScript.
Como um exemplo trivial e inútil, uma calculadora JavaScript simplista:
Um exemplo de uso correto são alguns dos empacotadores JavaScript que compactam o JavaScript, retirando palavras comuns e substituindo-as por substituições curtas de 1-2 caracteres. O empacotador gera tudo isso junto com o código de substituição de string com base no dicionário gerado e avalia o resultado.
fonte
Há algumas coisas que são impossíveis de fazer em JS sem uma função eval-like (
eval
,Function
e talvez mais).Tome
apply
por exemplo. É fácil de usar ao usá-lo em chamadas de funções comuns:foo.apply(null, [a, b, c])
Mas como você faria isso para objetos que você está criando através de nova sintaxe?
new Foo.apply(null, [a, b, c])
não funciona, nem formas semelhantes.Mas você pode contornar essa limitação via
eval
ouFunction
(eu usoFunction
neste exemplo):Exemplo:
Foo.New.apply(null, [a, b, c])
;Obviamente, você pode criar manualmente as funções que
Function.prototype.New
usa, mas não apenas isso é detalhado e desajeitado, mas (por definição) precisa ser finito.Function
permite que o código funcione para qualquer número de argumentos.fonte
eval()
? "Uma resposta direta da minha parte foi o desenvolvimento de uma área de teste de API orientada ao desenvolvedor. Fornecemos uma área de texto em uma página e um botão Executar. O ponto central da página era que eles pudessem experimentar coisas em Javascript contra nossa API de comunicação de iframe que não era tão fácil de fazer em um ambiente local.
Qualquer coisa maliciosa que pudesse ter sido feita nesse caso também poderia ter sido feita pelo desenvolvedor abrindo suas ferramentas F12.
fonte
Concordo que raramente deve ser usado, mas encontrei um caso de uso poderoso para
eval
.Há um novo recurso experimental no Firefox chamado asm.js com o qual estou trabalhando. Ele permite que um subconjunto limitado da linguagem Javascript seja compilado no código nativo. Sim, isso é muito impressionante, mas tem limitações. Você pode pensar no subconjunto limitado de Javascript como uma linguagem semelhante a C incorporada ao Javascript. Não é realmente para ser lido ou escrito por humanos.
Esse subconjunto limitado de Javascript não permite que eu injete meu código gerado em tempo de execução no código compilado depois de compilado.
Eu escrevi um código que permite ao usuário escrever, em notação familiar, uma expressão matemática e convertê-la rapidamente para o código asm.js. A menos que eu queira que o código seja processado no lado do servidor (o que não
eval
é o caso ), é a única ferramenta que me permite processar o código resultante pelo navegador em tempo real.fonte
Conforme apontado por outros, a coisa mais importante quando se trabalha
eval
é mantê-lo seguro. Para isso, você deseja fazer uma verificação completa de argumentos e mantereval
o código simples, pois geralmente é muito mais difícil manter e proteger o código gerado em tempo de execução.Dito isto, gosto de usar
eval
para dois tipos de coisas (mesmo que provavelmente haja alternativas melhores e menos malignas):eval
é uma maneira de "colocar em cache explicitamente o código", ele pode ser usado para melhorar o desempenho. Observe que os otimizadores estão sempre sendo aprimorados, mas simplesmente não há garantia sobre o que eles podem fazer por você. Ao tornar as coisas explícitas no código, você realmente pode ajudar o otimizador a tomar decisões mais inteligentes.Essa abordagem do iterador de objetos pré-compilados , por exemplo, mostra benefícios claros de desempenho ao usar
eval
para iteração de propriedades de objetos. Também mostra o início de um poderoso sistema de tipos que pode fornecer verificação implícita de restrições e muito mais, com pouco ou nenhum custo.Muitos desenvolvedores experientes de Javascript provavelmente apontariam que essa é uma toca de coelho, pois, se você começar a escrever Javascript dessa maneira, alterará essencialmente a maneira como usa a linguagem. No entanto, isso pode não ser necessariamente algo ruim para quem gosta de Javascript, mas também está faltando recursos fundamentais da linguagem que só podem ser alcançados alterando a maneira como usamos a própria linguagem.
fonte
Eu tenho uma situação em que eval se parece com o caminho a percorrer, avaliando uma string e retornando uma variável existente cujo nome é o mesmo da string.
Eu tenho várias tabelas: table1ResultsTable, table2ResultsTable, tableNResultsTable. Eu tenho variáveis configuradas com os mesmos nomes, que são objetos de dados jQuery. Eu os uso para configurar as tabelas e chamar funções de dados do jQuery nelas.
Cada tabela possui class = "resultsTable" atribuído. Agora, preciso obter a variável quando a tabela é clicada. Eu estou fazendo isto:
Então, eu estou recebendo o ID da tabela na qual a célula foi clicada, que tem o mesmo nome que a variável de objeto de tabela de dados correspondente a ela. Se alguém tiver uma sugestão para uma melhoria, eu gostaria de saber sobre isso.
fonte
event.target.parentElement.parentElement.parentElement
é horrível. Além disso, eu esperaria que a chamada eval gere um erro "erro de referência: [id] não está definido", a menos que você esteja usando deliberadamente IDs avaliáveis (que estão quebrados, incorretos e podem causar coisas estranhas se você terminar gerar IDs duplicados).document.getElementById(ID).MySpecialProperty = MYSPECIALPROPERTYVALUE
(para não dizer que isso é ótimo também, mas é melhor que eval). Como Eric Lippert aponta, "todo objeto no JScript já é uma tabela de pesquisa".