tipos - Pasa una función de JavaScript como parámetro
pasar parametros a una funcion javascript desde html (13)
¿Cómo puedo pasar una función como parámetro sin que la función se ejecute en la función "principal" o usando eval()
? (Desde que leí eso es inseguro).
Tengo esto:
addContact(entityId, refreshContactList());
Funciona, pero el problema es que refreshContactList
se refreshContactList
cuando se llama a la función, en lugar de cuando se utiliza en la función.
Podría eval()
usando eval()
, pero no es la mejor práctica, de acuerdo con lo que he leído. ¿Cómo puedo pasar una función como parámetro en JavaScript?
Aquí hay otro enfoque:
function a(first,second)
{
return (second)(first);
}
a(''Hello'',function(e){alert(e+ '' world!'');}); //=> Hello world
De hecho, parece un poco complicado, no lo es.
Obtener el método como parámetro:
function JS_method(_callBack) {
_callBack("called");
}
Se puede dar como método de parámetro:
JS_method(function (d) {
//Finally this will work.
alert(d)
});
Ejemplo 1:
funct("z", function (x) { return x; });
function funct(a, foo){
foo(a) // this will return a
}
Ejemplo 2:
function foodemo(value){
return ''hello ''+value;
}
function funct(a, foo){
alert(foo(a));
}
//call funct
funct(''world!'',foodemo); //=> ''hello world!''
En algún momento en el que necesite lidiar con el controlador de eventos, deberá pasar el evento también como un argumento, la mayoría de las bibliotecas modernas, como reaccionar, angular, podrían necesitar esto.
Necesito anular la función OnSubmit (función de una biblioteca de terceros) con una validación personalizada en reactjs y pasé la función y el evento como a continuación
ORIGINALMENTE
<button className="img-submit" type="button" onClick=
{onSubmit}>Upload Image</button>
HIZO UNA NUEVA FUNCIÓN upload
y llamar a pasar en onSubmit
y evento como argumentos
<button className="img-submit" type="button" onClick={this.upload.bind(this,event,onSubmit)}>Upload Image</button>
upload(event,fn){
//custom codes are done here
fn(event);
}
Hay una frase entre los programadores de JavaScript: "Eval es malvado", ¡así que trata de evitarlo a toda costa!
Además de la respuesta de Steve Fenton, también puede pasar funciones directamente.
function addContact(entity, refreshFn) {
refreshFn();
}
function callAddContact() {
addContact("entity", function() { DoThis(); });
}
Las otras respuestas hacen un excelente trabajo describiendo lo que está sucediendo, pero un "entendido" importante es asegurarse de que todo lo que se transmita sea una referencia a una función.
Por ejemplo, si pasa a través de una cadena en lugar de una función, obtendrá un error:
function function1(my_function_parameter){
my_function_parameter();
}
function function2(){
alert(''Hello world'');
}
function1(function2); //This will work
function1("function2"); //This breaks!
Ver JsFiddle
Me corté todo el pelo con ese problema. No pude hacer que los ejemplos anteriores funcionaran, así que terminé como:
function foo(blabla){
var func = new Function(blabla);
func();
}
// to call it, I just pass the js function I wanted as a string in the new one...
foo("alert(''test'')");
Y eso funciona a la perfección ... al menos para lo que necesitaba. Espero que pueda ayudar a algunos.
Para pasar la función como parámetro, simplemente quite los soportes!
function ToBeCalled(){
alert("I was called");
}
function iNeedParameter( paramFunc) {
//it is a good idea to check if the parameter is actually not null
//and that it is a function
if (paramFunc && (typeof paramFunc == "function")) {
paramFunc();
}
}
//this calls iNeedParameter and sends the other function to it
iNeedParameter(ToBeCalled);
La idea detrás de esto es que una función es bastante similar a una variable. En lugar de escribir
function ToBeCalled() { /* something */ }
bien podrías escribir
var ToBeCalledVariable = function () { /* something */ }
Hay pequeñas diferencias entre los dos, pero de todos modos, ambos son formas válidas de definir una función. Ahora, si define una función y la asigna explícitamente a una variable, parece bastante lógico, que puede pasarla como parámetro a otra función, y no necesita corchetes:
anotherFunction(ToBeCalledVariable);
Si desea pasar una función, solo haga referencia a ella por su nombre sin los paréntesis:
function foo(x) {
alert(x);
}
function bar(func) {
func("Hello World!");
}
//alerts "Hello World!"
bar(foo);
Pero a veces es posible que desee pasar una función con argumentos incluidos , pero no que se llame hasta que se invoque la devolución de llamada. Para hacer esto, al llamarlo, simplemente envuélvalo en una función anónima, como esta:
function foo(x) {
alert(x);
}
function bar(func) {
func();
}
//alerts "Hello World!" (from within bar AFTER being passed)
bar(function(){ foo("Hello World!") });
Si lo prefiere, también podría usar la función de apply y tener un tercer parámetro que sea una matriz de argumentos, como por ejemplo:
function eat(food1, food2)
{
alert("I like to eat " + food1 + " and " + food2 );
}
function myFunc(callback, args)
{
//do stuff
//...
//execute callback when finished
callback.apply(this, args);
}
//alerts "I like to eat pickles and peanut butter"
myFunc(eat, ["pickles", "peanut butter"]);
Solo necesitas quitar el paréntesis:
addContact(entityId, refreshContactList);
Esto luego pasa la función sin ejecutarlo primero.
Aquí hay un ejemplo:
function addContact(id, refreshCallback) {
refreshCallback();
// You can also pass arguments if you need to
// refreshCallback(id);
}
function refreshContactList() {
alert(''Hello World'');
}
addContact(1, refreshContactList);
Sugiero colocar los parámetros en una matriz y luego dividirlos usando la función .apply()
. Así que ahora podemos pasar fácilmente una función con muchos parámetros y ejecutarla de una manera sencilla.
function addContact(parameters, refreshCallback) {
refreshCallback.apply(this, parameters);
}
function refreshContactList(int, int, string) {
alert(int + int);
console.log(string);
}
addContact([1,2,"str"], refreshContactList); //parameters should be putted in an array
También puede utilizar un JSON para almacenar y enviar funciones JS.
Compruebe lo siguiente:
var myJSON =
{
"myFunc1" : function (){
alert("a");
},
"myFunc2" : function (functionParameter){
functionParameter();
}
}
function main(){
myJSON.myFunc2(myJSON.myFunc1);
}
Esto imprimirá ''a''.
Lo siguiente tiene el mismo efecto que lo anterior:
var myFunc1 = function (){
alert(''a'');
}
var myFunc2 = function (functionParameter){
functionParameter();
}
function main(){
myFunc2(myFunc1);
}
Que también tiene el mismo efecto con lo siguiente:
function myFunc1(){
alert(''a'');
}
function myFunc2 (functionParameter){
functionParameter();
}
function main(){
myFunc2(myFunc1);
}
Y un paradigma de objeto utilizando Clase como prototipo de objeto:
function Class(){
this.myFunc1 = function(msg){
alert(msg);
}
this.myFunc2 = function(callBackParameter){
callBackParameter(''message'');
}
}
function main(){
var myClass = new Class();
myClass.myFunc2(myClass.myFunc1);
}
También puedes usar eval()
para hacer lo mismo.
//A function to call
function needToBeCalled(p1, p2)
{
alert(p1+"="+p2);
}
//A function where needToBeCalled passed as an argument with necessary params
//Here params is comma separated string
function callAnotherFunction(aFunction, params)
{
eval(aFunction + "("+params+")");
}
//A function Call
callAnotherFunction("needToBeCalled", "10,20");
Eso es. También estaba buscando esta solución y probé las soluciones proporcionadas en otras respuestas, pero finalmente conseguí que funcionara con el ejemplo anterior.