Эти две функции делают то же самое за кулисами? (в функциях с одним оператором)
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
источник
источник
new
рассматривается в этом обсуждении?Function
неявно создает экземплярfunction object
. Исключениеnew
вообще не изменит код. Вот jsfiddle, демонстрирующий это: jsfiddle.net/PcfG8Ответы:
Нет, они не такие.
eval()
оценивает строку как выражение JavaScript в текущей области выполнения и может обращаться к локальным переменным.new Function()
анализирует код JavaScript, хранящийся в строке, в объект функции, который затем может быть вызван. Он не может получить доступ к локальным переменным, потому что код выполняется в отдельной области.Рассмотрим этот код:
function test1() { var a = 11; eval('(a = 22)'); alert(a); // alerts 22 }
Если бы
new Function('return (a = 22);')()
они использовались, локальная переменнаяa
сохранила бы свое значение. Тем не менее, некоторые программисты JavaScript , такие как Дуглас Crockford считают , что ни один не должно использоваться , если это абсолютно необходимо , и evaling / с помощьюFunction
конструкторы на ненадежных данных является небезопасным и неразумно.источник
new Function(code)
это то же самое,eval('(function(){'+code+'})()')
или это совершенно новый контекст выполнения?eval('(function(){'+code+'})')
, что возвращает объект функции. Согласно MDN , «функции, созданные с помощью конструктора функций, не создают замыканий для своих контекстов создания; они всегда выполняются в контексте окна (если только тело функции не начинается с оператора« use strict », и в этом случае контекст не определен). . "Нет.
В вашем обновлении вызовы
evaluate
иfunc
дают одинаковый результат. Но они определенно не «делают то же самое за кулисами».func
Функция создает новую функцию, но затем сразу же выполняет его, в то время какevaluate
функция просто выполняет код на месте.Из исходного вопроса:
var evaluate = function(string) { return eval(string); } var func = function(string) { return (new Function( 'return (' + string + ')' )()); }
Это даст вам очень разные результаты:
evaluate('0) + (4'); func('0) + (4');
источник
return eval('(' + string + ')');
тогда они дали бы те же результаты.new Function
создает функцию, которую можно использовать повторно.eval
просто выполняет заданную строку и возвращает результат последнего оператора. Ваш вопрос ошибочен, поскольку вы пытались создать функцию-оболочку, которая использует Function для имитации eval.Правда ли, что они разделяют какой-то код за кулисами? Да, очень вероятно. Точно такой же код? Нет, конечно.
Ради интереса, вот моя собственная несовершенная реализация с использованием eval для создания функции. Надеюсь, это проливает свет на разницу!
function makeFunction() { var params = []; for (var i = 0; i < arguments.length - 1; i++) { params.push(arguments[i]); } var code = arguments[arguments.length - 1]; // Creates the anonymous function to be returned // The following line doesn't work in IE // return eval('(function (' + params.join(',')+ '){' + code + '})'); // This does though return eval('[function (' + params.join(',')+ '){' + code + '}][0]'); }
Самая большая разница между этой функцией и новой функцией заключается в том, что функция не имеет лексической области видимости. Так что у него не было бы доступа к закрывающим переменным, как у меня.
источник
arguments.slice()
вместо цикла for? Или , если аргументы не является истинным массив[].slice.call(arguments, 1)
.Просто хочу указать на синтаксис, используемый в приведенных здесь примерах, и на то, что он означает:
var func = function(string) { return (new Function( 'return (' + string + ')' )()); }
обратите внимание, что функция (...) () имеет в конце "()". Этот синтаксис заставит func выполнить новую функцию и вернуть строку, а не функцию, которая возвращает строку, но если вы используете следующее:
var func = function(string) { return (new Function( 'return (' + string + ')' )); }
Теперь func вернет функцию, возвращающую строку.
источник
Если вы имеете в виду, даст ли он те же результаты, тогда да ... но просто eval (также известный как «оценить эту строку JavaScript») было бы намного проще.
ИЗМЕНИТЬ ниже:
Это как сказать ... эти две математические задачи одинаковы:
1 + 1
1 + 1 + 1 - 1 + 1 - 1 * 1/1
источник
Function
объект, вероятно, хранит строку в частной переменной-члене,eval
когда вы вызываете функцию.В этом примере результаты такие же, да. Оба выполняют переданное вами выражение. Вот что делает их такими опасными.
Но за сценой они делают разные вещи. Тот, который вовлекает
new Function()
за кулисами, создает анонимную функцию из предоставленного вами кода, который выполняется при вызове функции.Переданный вами код JavaScript технически не выполняется, пока вы не вызовете анонимную функцию. Это отличается от того,
eval()
что выполняет код сразу, а не генерирует на его основе функцию.источник
Does the Function() one use another stack call level than eval?
: Я бы так предположил, потомуeval()
что не создает функцию из вашего ввода - он просто выполняет ее.new Function()
создает новую функцию, которую затем вызывает.