Я пытаюсь создать простой REPL, убрав строки, предоставленные пользователем. Похоже, что он работает по большей части, за исключением входных данных, таких как «function f() {...}», которые не влияют на то, какие функции видны в будущих оценках. Поиграв с ним немного, я могу только заключить, что я вообще не понимаю eval. Вот короткий отрывок демонстрирует некоторые загадочные поведения:Определения функции определения уязвимости (... в JavaScript)
var xeval = eval;
function silly() {}
eval("function good() {}");
function baffleMe() {
eval("alsoGood = function() {}");
eval("function notSoGood() {}");
xeval("function hope() {}");
xeval("function crushedHope() { silly(); }");
}
baffleMe();
good(); // Okay.
alsoGood(); // Okay.
notSoGood(); // ReferenceError: notSoGood is not defined
hope(); // Why does this even work?
crushedHope(); // ReferenceError: silly is not defined
Может кто-нибудь объяснить эти результаты, пожалуйста? (Возпроизводимые как в последней Chrome и Firefox)
[EDIT]
Для уточнения, последний вызов не выполняется только тогда, когда код выполняется в консоли Javascript или инструменты, такие как JSFiddle, но не тогда, когда встроенный в сценарии тег. Комментарии к принятому ответу содержат объяснение этого.
См. Разницу между 'window.eval' (' global.eval' в узле) и 'eval' – elclanrs
тесно связан: [глобальный.eval не может посещать переменные в лексической области] (http://stackoverflow.com/q/31459180/710446) – apsillers
Если вы собираетесь сделать REPL, вы должны поместить оценки строк в выражения 'try catch' , и если сообщение об ошибке «Неожиданный конец ввода», тогда запрос на получение большего количества кода до тех пор, пока не будет выполнен «eval» или не приведет к другой ошибке. –