2008-10-22 30 views
68

Estoy intentando descubrir cómo pasar argumentos a una función anónima en JavaScript.¿Cómo puedo pasar argumentos a funciones anónimas en JavaScript?

Salida este código de ejemplo y creo que usted verá lo que quiero decir:

<input type="button" value="Click me" id="myButton" /> 

<script type="text/javascript"> 
    var myButton = document.getElementById("myButton"); 
    var myMessage = "it's working"; 
    myButton.onclick = function(myMessage) { alert(myMessage); }; 
</script> 

Al hacer clic en el botón del mensaje: debe aparecer. Sin embargo, la variable myMessage dentro de la función anónima es nula.

jQuery usa muchas funciones anónimas, ¿cuál es la mejor manera de pasar ese argumento?

+0

Cierres: http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html – mishal153

Respuesta

62

su caso específico, simplemente se puede corregir estar funcionando:

<script type="text/javascript"> 
    var myButton = document.getElementById("myButton"); 
    var myMessage = "it's working"; 
    myButton.onclick = function() { alert(myMessage); }; 
</script> 

Este ejemplo funcionará porque la función anónima creada y asignada como un controlador de elemento tendrá acceso a las variables definidas en el contexto en el que fue creado.

Para el registro, un controlador (que se asigna a través del establecimiento de XXX propiedad) espera solo argumento para tomar que es objeto de evento que se pasa por el DOM, y no se puede obligar a pasar otro argumento allí

9

Mediante la eliminación de la el parámetro de la función anónima estará disponible en el cuerpo.

myButton.onclick = function() { alert(myMessage); }; 

Para obtener más información sobre búsqueda de 'javascript' cierres

+0

necesitaba para leer sobre "cierres javascript" como ha afirmado .. Gracias! – hakksor

22

Lo que has hecho no funciona porque estás un enlace de sucesos a una función. Como tal, es el evento el que define los parámetros que se invocarán cuando se genere el evento (es decir, JavaScript no conoce tu parámetro en la función a la que te has limitado a hacer clic, por lo que no puede pasarle nada).

Usted podría hacer esto sin embargo:

<input type="button" value="Click me" id="myButton"/> 

<script type="text/javascript"> 

    var myButton = document.getElementById("myButton"); 

    var myMessage = "it's working"; 

    var myDelegate = function(message) { 
     alert(message); 
    } 

    myButton.onclick = function() { 
     myDelegate(myMessage); 
    }; 

</script> 
+0

No puedo ver cómo el lambda entiende el mensaje, que asigna su valor de retorno a myDelegate. He visto lambdas como función (a, b) { // código aquí } (a, b); –

0

Lo que ha hecho que se crea una nueva función anónima que toma un único parámetro que luego se asigna a la variable local myMessage dentro de la función. Como en realidad no se pasan argumentos, y los argumentos que no se pasan un valor se vuelven nulos, su función solo alerta (nulo).

0

Si usted lo escribe como

myButton.onclick = function() { alert(myMessage); }; 

Se trabajará, pero no sabe si eso responde a sus preguntas.

1

Ejemplo:

<input type="button" value="Click me" id="myButton"> 
<script> 
    var myButton = document.getElementById("myButton"); 
    var test = "zipzambam"; 
    myButton.onclick = function(eventObject) { 
     if (!eventObject) { 
      eventObject = window.event; 
     } 
     if (!eventObject.target) { 
      eventObject.target = eventObject.srcElement; 
     } 
     alert(eventObject.target); 
     alert(test); 
    }; 
    (function(myMessage) { 
     alert(myMessage); 
    })("Hello"); 
</script> 
+0

Un cambio: eventObject = eventObject || window.event; Un cambio más: eventObject = eventObject || window.event || {}; – eyelidlessness

+0

Otro cambio: eventObject.target = eventObject.target || eventObject.srcElement || nulo; – eyelidlessness

1

Los delegados:

function displayMessage(message, f) 
{ 
    f(message); // execute function "f" with variable "message" 
} 

function alerter(message) 
{ 
    alert(message); 
} 

function writer(message) 
{ 
    document.write(message); 
} 

ejecutar la función mostrarMensaje:

function runDelegate() 
{ 
    displayMessage("Hello World!", alerter); // alert message 

    displayMessage("Hello World!", writer); // write message to DOM 
} 
5

Los controladores de eventos esperan un parámetro que es el evento que se disparó. Está cambiando el nombre a 'myMessage' y, por lo tanto, está alertando al objeto del evento en lugar de a su mensaje.

Un cierre puede permitirle hacer referencia a la variable que ha definido fuera de la función; sin embargo, si está utilizando Jquery, puede consultar su API específica de evento, p.

http://docs.jquery.com/Events/bind#typedatafn

Esto tiene una opción para pasar en sus propios datos.

3
<input type="button" value="Click me" id="myButton" /> 

<script type="text/javascript"> 
    var myButton = document.getElementById("myButton"); 

    myButton.myMessage = "it's working"; 

    myButton.onclick = function() { alert(this.myMessage); }; 


</script> 

Esto funciona en mi suite de pruebas que incluye todo desde IE6 +. La función anónima conoce el objeto al que pertenece, por lo que puede pasar datos con el objeto que lo está llamando (en este caso myButton).

20

El siguiente es un método para usar cierres para solucionar el problema al que se refiere. También tiene en cuenta el hecho de que puede cambiar el mensaje a lo largo del tiempo sin afectar la vinculación. Y usa jQuery para ser sucinto.

var msg = (function(message){ 
    var _message = message; 
    return { 
    say:function(){alert(_message)}, 
    change:function(message){_message = message} 
    }; 
})("My Message"); 
$("#myButton").click(msg.say); 
+0

Estoy aprendiendo. ¿Por qué asigna a '_message'? ¿Por qué no usar 'mensaje'? –

+0

En este caso, lo estoy haciendo para que el alcance interno del método de cambio pueda tener una firma válida, de lo contrario no habría forma de cambiar el valor del mensaje en el cierre externo. – Gabriel

+0

Excelente respuesta usando un cierre. Sin embargo, cambiaría el nombre del argumento de función "cambiar" porque "mensaje" es engañoso, debería ser más claro que no está relacionado con el argumento externo "mensaje". esa función se puede refactorizar de esta manera: change: function (newmessage) {_ message = newmessage} –

Cuestiones relacionadas