Как создать интерпретатор JavaScript в JavaScript с помощью eval?
Должно быть просто создать JavaScript-интерпретатор в JavaScript, используя eval
, Я получил это (используя терминал jQuery):
term = $('#term_demo').terminal(function(command, term) {
if (command !== '') {
var result = window.eval("(" + command + ")");
if (result !== undefined) {
term.echo(String(result));
}
} else {
term.echo('');
}
}, {
greetings: 'Javascript Interpreter',
name: 'js_demo',
height: 200,
prompt: 'js> '
});
но это не работает, когда я выполняю function foo() { ... }
foo
не определено мне нужно использовать foo = function() { ... }
, Eval Act, как исполненный в (function() { <code> })()
, Может ли быть более сложный код, который тоже не будет работать?
Можно ли создать интерпретатор JavaScript с использованием простого кода без использования js.js, который будет работать так же, как консоль браузера?
2 ответа
Я создал букмарклет, который добавляет на страницу своего рода REPL, предназначенный для пяти основных браузеров (Chrome 1+, IE 6+, Firefox 1+, Safari 3+, Opera 9+.Не могу вспомнить точную версию),
Основной компонент, который оценивает код, размещен ниже, слегка изменен + аннотирован.
/**
* Evaluates some code in the global scope.
* @param String code: Code to eval
* @return Stringified result, prefixed with 'E:' if error.
*/
function globalEval(/*string*/ code) {
var win = window, r, raw;
try {
if (win.execScript) { // eval in IE sucks, so use execScript instead
r = win.$_$_$globalEval$_$_$ = {c:code};
win.execScript('try{$_$_$globalEval$_$_$.r=eval($_$_$globalEval$_$_$.c);}catch(e){$_$_$globalEval$_$_$.e=e}');
// /*Optional clean-up:*/ delete win.$_$_$globalEval$_$_$;
if (r.e) throw r.e; // Error
raw = r.r;
} else {
raw = win.eval(code);
}
r = '' + raw; // Stringify in the try-block
// It is possible that an error is thrown
// for example, for the following code: ({toString:1})
} catch(err) {
r = (err + ''); // Convert error to string
// IE: If found, "[object" will be at index zero, which is falsy
if (!r.indexOf('[object')) r = err.message;
// r =
r = 'E:' + (raw=r);
} finally {
// raw = unmodified result (or Error instance)
// FOR THIS EXAMPLE, raw is not used, and string r is returned
return /*string*/ r;
}
}
Я реализовал функциональность в форме, которая содержит несколько элементов управления, включая текстовую область ввода + вывода.
Примечание. Код оценивается в глобальном контексте. И такие, любые переменные в code
будет просочился в глобальную сферу. Для интерпретатора вы можете использовать iframe для создания новой области видимости (и изменить var win
в моей функции).
var win = frames['name_of_frame'], ... // or
var win = frame_DOM_element.contentWindow, ...
Скобки, которые вы добавляете к входящей команде, приводят к недопустимому синтаксису. Вы должны вместо этого обернуть его анонимной самореализующейся функцией.
Пример: http://jsfiddle.net/bW6Fv/1/
var command = "function foo(x){return x+x;} alert(foo(10));";
window.eval("!function(){" + command + "}()");
РЕДАКТИРОВАТЬ
Если вы хотите, чтобы ваши оцененные сценарии были доступны глобально, вам придется оставить их развернутыми или явно назначить значения глобальному объекту окна.
Пример: http://jsfiddle.net/bW6Fv/2/
var command = "window.foo = function(x){return x+x;}; alert(foo(10));";
window.eval("!function(){ " + command + "}();");
window.eval("alert(foo(20));");
command = "function bar(x){return x / 2;}; alert(bar(10));";
window.eval(command);
window.eval("alert(bar(20));");