Javascript eval в глобальном масштабе?
Можно ли использовать команду eval для выполнения чего-либо с глобальной областью? Например, это приведет к ошибке:
<script>
function execute(x){
eval(x);
}
function start(){
execute("var ary = new Array()");
execute("ary.push('test');"); // This will cause exception: ary is not defined
}
</script>
<html><body onLoad="start()"></body></html>
Я знаю, что ключевое слово 'с' задает конкретную область видимости, но есть ли ключевое слово для глобальной области? Или можно определить настраиваемую область, которая позволила бы этому работать?
<script>
var scope = {};
function execute(x){
with(scope){
eval(x);
}
}
function start(){
execute("var ary = new Array()");
execute("ary.push('test');"); // This will cause exception: ary is not defined
}
</script>
<html><body onLoad="start()"></body></html>
По существу, я пытаюсь выполнить глобальную функцию выполнения...
Ответы
Ответ 1
(function(){
eval.apply(this, arguments);
}(a,b,c))
Это вызовет eval, используя глобальный объект window
в браузерах, в качестве аргумента this
, передающего любые аргументы, которые вы передали анонимной функции.
eval.call(window, x, y, z)
или eval.apply(window, arguments)
также действителен, если вы уверены, что window
- глобальный объект. Однако это не всегда так. Например, глобальный объект в Node.js script является process
, если я правильно помню.
Ответ 2
Вы можете использовать eval()
в глобальной области, косвенно вызывая его. Однако не все браузеры в настоящее время делают это.
Дополнительная литература.
Ответ 3
Используйте (1, eval)('...')
.
$ node
> fooMaker = function () { (1, eval)('foo = "bar"'); };
[Function]
> typeof foo
'undefined'
> fooMaker()
undefined
> typeof foo
'string'
> foo
'bar'
Ответ 4
Чтобы выполнить некоторый JavaScript в глобальной области действия, вы можете называть его косвенно, используя setTimeout() или если вы используете jQuery, посмотрите в $. globalEval().
Изменение вашего метода выполнения на следующее позволит вам по-прежнему использовать ключевое слово 'var':
function execute(x) {
setTimeout("eval(" + x + ")", 0);
// Or: $.globalEval(x);
}
function start() {
try
{
execute("var ary = new Array()");
execute("ary.push('test');");
}
catch (e)
{
alert(e);
}
}
start();
Ответ 5
Я знаю, что комментариев с eval будет много, и я согласен с этим.
Однако, чтобы ответить на ваш вопрос, измените свой метод запуска следующим образом:
function start(){
execute("ary = new Array()");
execute("ary.push('test');"); // This will cause exception: ary is not defined
}
Ответ 6
Используйте eval.apply(null, ["code"]);
.
eval.apply(this, ["code"]);
не работает с Microsoft Script Host (cscript.exe).