Есть ли веская причина для передачи строки в setTimeout? - PullRequest
22 голосов
/ 21 мая 2011

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

setTimeout('doSomething(someVar)', 10000);

в пользу этого:

setTimeout(function() {
    doSomething(someVar);
}, 10000);

Мой вопрос: может ли быть причина, чтобы сделать первое?Это когда-либо предпочтительнее?Если это не так, почему это вообще разрешено?

Единственный сценарий, о котором я подумал, - это желание использовать функцию или переменную, которая существует в глобальной области, но была переопределена в локальной области.Это звучит как плохой дизайн кода, однако ...

Ответы [ 2 ]

16 голосов
/ 21 мая 2011

Вы всегда можете использовать глобальные переменные, обращаясь к ним как к свойствам объекта окна, например window.globalVar (хотя использование глобальных переменных действительно не очень хорошая практика), поэтому нет, я не думаю, что когда-либо есть веская причинаиспользуйте устаревший синтаксис.

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

Представлено в JavaScript 1.0, Netscape 2.0. Передача ссылки на объект Function появилась в JavaScript 1.2, Netscape 4.0 ;поддерживается MSHTML DOM начиная с версии 5.0.[ source , мой акцент]

Если браузеры больше не поддерживают использование строки в качестве первого аргумента для setTimeout и setInterval, будет многокод в интернете, который больше не работает.

15 голосов
/ 12 августа 2014

Для тех, кто перенаправлен сюда вопросом , почему передача функции лучше, чем передача строки .

1: передача строки запускает компилятор

Каждый раз, когда вам нужно оценить строку, вы запускаете полный компилятор.Для каждого вызова, где это необходимо.

Мало того, что это медленно, это разрушает все ускорения JIT и браузера, которые сделаны.

2: Передача строкиНАМНОГО более ограничено.

Поскольку строка запускается через компилятор, она не так четко связана с локальной областью видимости и переменными.

Хотя это не заметно в ситуациинапример:

window.setInterval("doThing()");

В более сложной ситуации код выглядит чище:

window.setInterval("doThing(" + val1 + "," + val2 + ")");

против

window.setInterval(function() {
  // You can put a debugging point here
  dothing(val1, val2);
});

3: объекты DOM могутне могут передаваться через строку

Как уже упоминал Альваро, объекты DOM не могут быть переданы с помощью строкового метода.

// There is no way to do this via a string.
var el = document.getElementById("my-element");
window.setInterval(function() {
  dothing(el);
});

(Другие объекты могут или не могут быть пройдены -в зависимости от того, можно ли их сериализовать, но в целом это будет довольно сложно.)

...