2012-05-13 9 views
6

Quiero pasar un argumento a una función llamada usando setTimeout. He encontrado estas tres opciones:¿Cómo puedo pasar un argumento a una función llamada usando setTimeout?

A = 1; 
// Method 1: closure things 
setTimeout(function() { whatsA(A); }, 100); 
// Method 2: third argument (same result with [A]) 
setTimeout(whatsA, 100, A); 
// Method 3: eval 
setTimeout('whatsA(' + A + ')', 100); 
A = 2; 
function whatsA(X) { console.log(X); } 

Esto demuestra 2, undefined, y 1 en Internet Explorer 9.

Método 1: Claramente, no me gustaría que el argumento que ser cambiado después de pasarlo (ciertamente en el caso de números enteros simples).

Método 2: Esto sería perfecto si solo lo admite Internet Explorer.

Método 3: Esta parece ser la única opción. Pero parece bastante menos bonito que los otros, pasando algo para ser evaluado en lugar de una función.

¿Hay una manera mejor?

+2

Método 3 es el que debe **nunca usar. Y el Método 2 está en desuso, incluso en los navegadores gecko, por lo que incluso sin tener soporte para IE, es casi un no-go. – ThiefMaster

Respuesta

7

La mejor solución que se me ocurre es el uso de bind():

A = 1; 
setTimeout(whatsA.bind(this, A), 100); 

Debido bind() es en realidad una invocación de la función, se lee el valor actual A y devuelve una función con ese valor obligado como un argumento. Si le resulta difícil de entender, intente esto:

var newFun = whatsA.bind(this, 42); 
newFun() 

Tenga en cuenta que es una especie de this una mentira aquí - se puede pasar con seguridad window también.


El primer método es también aceptable, que sólo necesita ser mejorado ligeramente:

A = 1; 
var tmpA = A; 
setTimeout(function() { whatsA(tmpA); }, 100); 

lo que está observando es en realidad una característica, no un error. Está pasando un cierre al setTimeout() haciendo referencia a la variable local. JavaScript es lo suficientemente inteligente como para retrasar el acceso a esa variable hasta el momento en que se llama realmente a la función. Y como ha modificado la variable, verá la versión más reciente.


El segundo método es obsoleto no funcionará en cualquier navegador.


tercer método es terrible, evitar la transmisión de cadena a setTimeout(), siempre hay una solución mejor.

+0

También hay soluciones 'whatsA.apply (this, [A])' y 'whatsA.call (this, A)'. – VisioN

+0

+1 para la solución limpia '.bind()'. @VisionN: Sin embargo, esas versiones requerirían la función de auto-llamada para evitar cerrar la variable. – ThiefMaster

+0

* puede pasar con seguridad la ventana también * - o 'null' que es más limpio en mi humilde opinión. – ThiefMaster

4

Usted podría utilizar el cierre:

setTimeout((function(A){ 
       return function(){ 
        whatsA(A); 
       }; 
      })(A), 100); 
+0

+1 ¡Muy buena idea! – VisioN

0

de sus tres métodos:

Opción 1:

setTimeout(function() { whatsA(A); }, 100);

Esto se trabaja en todas partes y es simple.Es lo que recomendaría a menos que la variable A cambie antes de llamar a la función setTimeout. Si necesita congelar el valor de A, entonces vea mi opción 4 a continuación.


Opción 2:

setTimeout(whatsA, 100, A);

Esto sólo funciona en algunos navegadores. No recomendado.


Opción 3:

setTimeout('whatsA(' + A + ')', 100);

Esto nunca es recomendable. Construir código como una cadena y luego evaluarlo más tarde casi nunca es la mejor solución.


recomendaría Opción 4:

para congelar el valor de A, puede crear un cierre mediante una función de ejecutar el self:

A = 1; 

function(A) { 
    setTimeout(function() {whatsA(A);}, 100); 
}(A); 

A = 2; 
function whatsA(X) { console.log(X); } 
Cuestiones relacionadas