Разница между ивала и setTimeout выполняет код строки


Я знаю, что eval и setTimeout могут принимать строку в качестве параметра (1-го), и я знаю, что мне лучше не использовать это. Мне просто интересно, почему есть разница:

!function() {
    var foo = 123;
    eval("alert(foo)");
}();

!function() {
    var foo = 123;
    setTimeout("alert(foo)", 0);
}();

Первый будет работать, а второй даст ошибку: foo is not defined

Как они исполняются за сценой?

5 6

5 ответов:

Смотрите ссылку setTimeout на MDN .

Строковые литералы вычисляются в глобальном контексте, поэтому локальные символы в контексте, где был вызван setTimeout (), не будут доступны, когда строка вычисляется как код.

Напротив, строковый литерал, передаваемый вeval () , выполняется в контексте вызова eval.

SetTimeout eval дополнительно выполняется в глобальной области, поэтому он не знает о foo.

Вот Ссылка для его резервного копирования:

Строковые литералы вычисляются в глобальном контексте, поэтому локальные символы в контексте, где был вызван метод setTimeout (), он недоступен. когда строка оценивается как код.

SetTimeout принимает больше параметров, чем функция reference и timeout. Все, что было введено после тайм-аута, будет передано в вашу функцию в качестве параметра.

setTimeout(myFunction(param1, param2), 0, param1, param2);
!function() {
    var foo = 123;
    eval("alert(foo)");
}();

При выполнении этого кода javascript будет делать вид, что строка 3 говорит " alert (foo)". Foo определяется в области действия функции.

!function() {
    var foo = 123;
    setTimeout("alert(foo)", 0);
}();

При выполнении этого кода javascript введет новую функцию, а именно function() {alert(foo)}. В области действия этой "новой" функции foo не определен.

В качестве дополнения к правильному ответу, вот вызов eval, который дал бы вам то же самое поведение, и ошибка в этом случае:

!function() {
    var foo = 123;
    window.eval("alert(foo)"); // <- note the window.eval, this is important and changes the behavior of the `eval` function
}();

!function() {
    var foo = 123;
    setTimeout("alert(foo)", 0);
}();

Этот пост в блоге подробно посвящен различным типам eval: http://perfectionkills.com/global-eval-what-are-the-options/