создавать анонимные методы, используя "eval" - специфическое поведение браузера - PullRequest
5 голосов
/ 14 июля 2010

Я работал с jQuery и мне нужно было создать анонимный метод с помощью функции eval ().

Следующие строки работали с Opera, но не с IE, FF, Chrome:

var callbackStr = "function(){alert('asdf');}";  
var callback = eval(callbackStr);  
callback();

Этот код работает со всеми браузерами:

var callbackStr = "var callback = function(){alert('asdf');}";  
eval(callbackStr);  
callback();  

Вы видите, яуже решил мою проблему.Но я хочу знать, что именно происходит.Кто-нибудь может объяснить мне это поведение или сказать, где я могу найти дополнительную информацию?

(PS: я знаю эту страницу .)

Ответы [ 4 ]

6 голосов
/ 14 июля 2010

Причина та же, что и необходимость заключать скобки в строки JSON перед использованием eval для них - eval рассматривает { как токен, начало оператора eval предполагаетанонимные функции - это FunctionDeclaration.Использование скобок позволяет eval рассматривать то, что внутри, как выражение:

var callbackStr = "(function(){alert('asdf');})";  
var callback = eval(callbackStr);  
callback();
// -> alerts 'asdf';

Что касается того, почему Opera ведет себя по-другому, я понятия не имею.Что касается вашего использования eval, возможно, есть лучший способ (он почти всегда есть).

Я нашел для вас цитату из спецификации, раздел 12.4 ECMA-262, третье издание :

Обратите внимание, что ExpressionStatement не может начинаться с открывающей фигурной скобки, поскольку это может сделать его неоднозначным с блоком. Кроме того, ExpressionStatement не может начинаться с ключевого слова function, потому что это может сделать его неоднозначным с FunctionDeclaration .

Выделить мое.

2 голосов
/ 14 июля 2010

первый пример будет работать, если вы сделаете свой eval следующим образом

var callbackStr = "function(){alert('asdf');}";  
var callback = eval("(" + callbackStr + ")");  
callback();
1 голос
/ 14 июля 2010

eval не возвращает такую ​​функцию. Вместо этого он выполняет фрагмент кода в глобальной области видимости, поэтому работает второй пример - в глобальной области видимости создается callback var.

Я уверен, что это просто чрезвычайно упрощенные примеры, но вы почти всегда можете избежать использования eval, что рекомендуется.

0 голосов
/ 14 июля 2010

Первый случай просто оценивает вашу строку и выполняет функцию.Он не возвращает указатель на эту конкретную функцию, поэтому вы не можете выполнить ее, вызвав функцию обратного вызова.

...