¿Existe alguna vez una buena razón para pasar una cadena a setTimeout?

Resuelto lonesomeday asked hace 13 años • 2 respuestas

Todos sabemos que pasar una cadena a setTimeout(o setInterval) es malo, porque se ejecuta en el ámbito global, tiene problemas de rendimiento, es potencialmente inseguro si se inyecta algún parámetro, etc. Por lo tanto, hacer esto definitivamente está en desuso:

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

a favor de esto:

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

Mi pregunta es: ¿puede haber alguna vez una razón para hacer lo primero? ¿ Alguna vez es preferible? Si no lo es, ¿por qué está permitido?

El único escenario en el que he pensado es querer utilizar una función o variable que existe en el ámbito global pero que ha sido anulada en el ámbito local. Sin embargo, eso me suena a un mal diseño de código...

lonesomeday avatar May 21 '11 18:05 lonesomeday
Aceptado

Siempre puedes usar variables globales accediendo a ellas como propiedades del objeto de ventana, como window.globalVar(aunque usar variables globales no es una buena práctica), así que no, no creo que haya alguna buena razón para usar la sintaxis obsoleta.

Probablemente esté permitido por razones históricas: como mencionó Felix Kling, la sintaxis original solo permitía pasar una cadena de código:

Introducido con JavaScript 1.0, Netscape 2.0. El paso de una referencia de objeto de función se introdujo con JavaScript 1.2, Netscape 4.0 ; soportado por MSHTML DOM desde la versión 5.0. [ fuente , énfasis mío]

Si los navegadores no admiten el uso de una cadena como primer argumento setTimeouty setIntervalmás, habrá mucho código en Internet que ya no funcionará.

Marcel Korpel avatar May 21 '2011 12:05 Marcel Korpel

Para aquellos que son redirigidos aquí por la pregunta de por qué pasar una función es mejor que pasar una cadena .

1: Pasar una cadena activa un compilador

Cada vez que tienes que evaluar una cadena, activas un compilador completo. Para todas y cada una de las invocaciones donde sea necesario.

Esto no sólo es lento, sino que destruye todos los JIT y aceleraciones del navegador que se realizan.

2: Pasar una cuerda es MUCHO más limitado.

Debido a que una cadena se ejecuta a través de un compilador, no está tan claramente vinculada al alcance y las variables locales.

Si bien no se nota en situaciones como:

window.setInterval("doThing()");

En una situación más compleja, el código es simplemente más limpio:

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

vs

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

3: los objetos DOM no se pueden pasar mediante una cadena

Como mencionó Álvaro, los objetos DOM no se pueden pasar mediante un método de cadena.

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

(Otros objetos pueden ser transitables o no, dependiendo de si se pueden serializar, pero en general sería bastante difícil).

Jeremy J Starcher avatar Aug 12 '2014 07:08 Jeremy J Starcher