¿Pasar una función con argumentos como argumento?

4 minutos de lectura

Avatar de usuario de Lucía
Lucía

¿Es posible pasar una función javascript con argumentos como argumento?

Ejemplo:

$(edit_link).click( changeViewMode( myvar ) );

  • Se parece a JQuery, y lo más probable es que lo sea, pero eso es irrelevante. El uso de parámetros y funciones es el mismo independientemente de las bibliotecas de Javascript que utilice.

    – Guffa

    19 de agosto de 2009 a las 14:18

  • Si está trabajando con React, considere stackoverflow.com/questions/41369497/…

    – Michael Freidgeim

    3 de febrero de 2020 a las 1:22

Utilice un “cierre”:

$(edit_link).click(function(){ return changeViewMode(myvar); });

Esto crea un contenedor de función temporal anónimo que conoce el parámetro y lo pasa a la implementación de devolución de llamada real.

  • Si desea llamar a una función en un objeto, debe llamar a bind(). myObj.click( function() { this.doSomething(); }.bind( myObj ) ); Eso hará que “esto” sea myObj.

    – Elí

    3 oct 2013 a las 22:19

  • ¿No es esto un problema de rendimiento cuando se trata de muchos de estos? Por ejemplo, está renderizando un onPress in a Row y tiene 10,000 filas. Esto crea un nuevo contenedor de función temporal anónimo para cada Fila. ¿Hay alguna otra forma de hacerlo?

    – Josué Pinter

    26 de noviembre de 2017 a las 18:23

  • @JoshuaPinter La técnica en sí no es un problema. Si necesita la misma llamada de función 10 000 veces, simplemente puede guardar el contenedor en una variable, de modo que lo cree solo una vez. Si necesita pasar 10,000 contextos diferentes, es poco lo que puede hacer. Tenga cuidado con la optimización prematura: como siempre con el rendimiento, debe medida para ver si hay un problema o no. Los motores de JavaScript actuales son muy potentes y pueden optimizar el código de formas sorprendentes.

    – Fernando Beyer

    27 de noviembre de 2017 a las 9:49

  • @FerdinandBeyer Impresionante, gracias por el consejo. Un amigo me dijo que era una mala práctica y que en su lugar deberías usar this.myFunction = this.myFunction.bind(this) en tus constructor método. Pero, como dijiste, cuando tienes que pasarle diferentes contextos para cada uno, como todas las filas diferentes en las que haces clic para abrir la página de detalles de esa fila, no es evitable.

    – Josué Pinter

    27 de noviembre de 2017 a las 23:41

  • En ES6 puede simplificarlo usando funciones de flecha. $(editar_enlace).click(() => changeViewMode(myvar));

    – rodrigombs

    22 de noviembre de 2020 a las 2:10


Usar Function.prototype.bind(). Citando a MDN:

El bind() método crea una nueva función que, cuando se llama, tiene su this palabra clave establecida en el valor proporcionado, con una secuencia dada de argumentos que preceden a cualquiera proporcionado cuando se llama a la nueva función.

Es compatible con todos los principales navegadores, incluido IE9+.

Su código debería verse así:

$(edit_link).click(changeViewMode.bind(null, myvar));

Nota al margen: supongo que está en un contexto global, es decir this variable es window; de lo contrario usar this en lugar de null.

  • Gracias, esto me ayudó. Lo usé así: $.ajax(url).done(handler.bind(this, var1, var2));

    – Tomás

    16 de junio de 2016 a las 10:13


  • ¿Qué opción es mejor? ¿Usando el cierre o usando la función de enlace? Por favor, hágame saber si hay algún impacto en el rendimiento.

    – Varún

    7 sep 2016 a las 8:50

  • @Varun Ver ¿Por qué el enlace es más lento que un cierre?

    – Michał Perłakowski

    7 sep 2016 a las 13:48

  • he estado usando fn.bind(this) para resolver el temido this confusión en las funciones de devolución de llamada sin comprender el propósito más amplio de bind – pero ahora lo entiendo! Gracias 🙏

    – encurtidos planos

    7 de junio de 2022 a las 5:58


No, pero puedes pasar uno sin parámetros y hacer esto:

$(edit_link).click(
  function() { changeViewMode(myvar); }
);

Entonces, está pasando una función anónima sin parámetros, esa función luego llama a su función parametrizada con la variable en el cierre

O si está usando es6, debería poder usar una función de flecha

$(edit_link).click(() => changeViewMode(myvar));

Sí, así:

$(edit_link).click(function() { changeViewMode(myvar) });

Avatar de usuario de Alexandr Sargsyan
Alejandro Sargsian

Puedes hacerlo

var message="Hello World";

var callback = function(){
alert(this)
}.bind(message);

y luego

function activate(callback){
  callback && callback();
}

activate(callback);

O si su devolución de llamada contiene una lógica más flexible, puede pasar el objeto.

Manifestación

avatar de usuario de erionpc
erionpc

Este es un ejemplo siguiendo el enfoque de Ferdinand Beyer:

function function1()
{
    function2(function () { function3("parameter value"); });
}
function function2(functionToBindOnClick)
{
    $(".myButton").click(functionToBindOnClick);
}
function function3(message) { alert(message); }

En este ejemplo, el “valor del parámetro” se pasa de la función 1 a la función 3 a través de la función 2 mediante un ajuste de función.

¿Ha sido útil esta solución?