Есть ли веская причина передать строку в setTimeout?
Мы все знаем, что передача строки в setTimeout
(или setInterval
) является злой, потому что она запущена в глобальной области, имеет проблемы с производительностью, потенциально небезопасна, если вы вводите какие-либо параметры и т.д. это явно не рекомендуется:
setTimeout('doSomething(someVar)', 10000);
в пользу этого:
setTimeout(function() {
doSomething(someVar);
}, 10000);
Мой вопрос: может ли быть когда-нибудь причина для первого? Всегда ли это предпочтительнее? Если это не так, почему это разрешено?
Единственный сценарий, о котором я думал, - это желание использовать функцию или переменную, которая существует в глобальной области, но была переопределена в локальной области. Это звучит для меня как плохой дизайн кода, однако...
Ответы
Ответ 1
Вы всегда можете использовать глобальные переменные, обращаясь к ним как к свойствам оконного объекта, например window.globalVar
(хотя использование глобальных переменных действительно не является хорошей практикой), поэтому нет, я не думаю, что когда-либо есть веская причина для используйте устаревший синтаксис.
Вероятно, это разрешено по историческим причинам: как отметил Феликс Клинг, исходный синтаксис позволил только передать строку кода:
Представлен с помощью JavaScript 1.0, Netscape 2.0. Передача ссылки объекта объекта Function была введена с помощью JavaScript 1.2, Netscape 4.0; поддерживаемый MSHTML DOM с версии 5.0. [источник, мой акцент]
Если браузеры больше не поддерживают использование строки в качестве первого аргумента для setTimeout
и setInterval
, в Интернете будет много кода, который больше не работает.
Ответ 2
Для тех, кто перенаправлен здесь вопросом о том, почему передача функции лучше, чем передача строки.
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);
});
(Другие объекты могут быть или не быть проходимыми - в зависимости от того, могут ли они быть сериализованы, но в целом это было бы довольно сложно.)