Essas duas funções estão fazendo a mesma coisa nos bastidores? (em funções de instrução única)
var evaluate = function(string) {
return eval('(' + string + ')');
}
var func = function(string) {
return (new Function( 'return (' + string + ')' )());
}
console.log(evaluate('2 + 1'));
console.log(func('2 + 1'));
javascript
function
optimization
eval
qwertymk
fonte
fonte
new
considerado nesta discussão?Function
instancia implicitamente afunction object
. A exclusãonew
não mudará o código de forma alguma. Aqui está um jsfiddle demonstrando que: jsfiddle.net/PcfG8Respostas:
Não, eles não são os mesmos.
eval()
avalia uma string como uma expressão JavaScript dentro do escopo de execução atual e pode acessar variáveis locais.new Function()
analisa o código JavaScript armazenado em uma string em um objeto de função, que pode então ser chamado. Ele não pode acessar variáveis locais porque o código é executado em um escopo separado.Considere este código:
Se
new Function('return (a = 22);')()
fosse usada, a variável locala
manteria seu valor. No entanto, alguns programadores de JavaScript, como Douglas Crockford, acreditam que nenhum dos dois deve ser usado a menos que seja absolutamente necessário , e avaliar / usar oFunction
construtor em dados não confiáveis é inseguro e imprudente.fonte
new Function(code)
é o mesmoeval('(function(){'+code+'})()')
ou é um contexto de execução totalmente novo?eval('(function(){'+code+'})')
, que retornaria um objeto de função. De acordo com o MDN , "as funções criadas com o construtor Function não criam fechamentos para seus contextos de criação; elas sempre são executadas no contexto da janela (a menos que o corpo da função comece com uma instrução" use strict ", caso em que o contexto é indefinido) . "Não.
Em sua atualização, as chamadas para
evaluate
efunc
produzem o mesmo resultado. Mas, eles definitivamente não estão "fazendo a mesma coisa nos bastidores". Afunc
função cria uma nova função, mas a executa imediatamente, enquanto aevaluate
função simplesmente executa o código no local.Da pergunta original:
Isso lhe dará resultados muito diferentes:
fonte
return eval('(' + string + ')');
, eles produziriam os mesmos resultados.new Function
cria uma função que pode ser reutilizada.eval
apenas executa a string fornecida e retorna o resultado da última instrução. Sua pergunta está equivocada, pois você tentou criar uma função de wrapper que usa Function para emular um eval.É verdade que eles compartilham algum código por trás das cortinas? Sim, muito provavelmente. Exatamente o mesmo código? Certamente.
Por diversão, aqui está minha própria implementação imperfeita usando eval para criar uma função. Espero que esclareça a diferença!
A maior diferença entre esta e a nova Função é que Function não tem escopo léxico. Portanto, ele não teria acesso às variáveis de fechamento e o meu teria.
fonte
arguments.slice()
vez do loop for? Ou se os argumentos não forem uma matriz verdadeira[].slice.call(arguments, 1)
,.Quero apenas apontar algumas sintaxes usadas nos exemplos aqui e o que isso significa:
observe que Function (...) () tem o "()" no final. Essa sintaxe fará com que func execute a nova função e retorne a string, não uma função que retorne string, mas se você usar o seguinte:
Agora func retornará uma função que retorna uma string.
fonte
Se você quer dizer, ele produzirá os mesmos resultados, então sim ... mas apenas avaliar (também conhecido como "avaliar esta string de JavaScript") seria muito mais simples.
EDITAR abaixo:
É como dizer ... esses dois problemas matemáticos são iguais:
1 + 1
1 + 1 + 1 - 1 + 1 - 1 * 1/1
fonte
Function
objeto provavelmente armazena a string em uma variável de membro privada atéeval
quando você invoca a função.Nesse exemplo, os resultados são os mesmos, sim. Ambos executam a expressão que você passa. Isso é o que os torna tão perigosos.
Mas eles fazem coisas diferentes por trás do scense. O que envolve
new Function()
, nos bastidores, cria uma função anônima a partir do código que você fornece, que é executada quando a função é chamada.O JavaScript que você passa para ele não é tecnicamente executado até que você invoque a função anônima. Isso contrasta com o
eval()
que executa o código imediatamente e não gera uma função baseada nele.fonte
Does the Function() one use another stack call level than eval?
: Eu diria que sim, porqueeval()
não cria uma função a partir de sua entrada - apenas a executa.new Function()
cria uma nova função, que então invoca.