Pass a JavaScript function as parameter - javascript
How do I pass a function as a parameter without the function executing in the "parent" function or using eval()? (Since I've read that it's insecure.)
I have this:
addContact(entityId, refreshContactList());
It works, but the problem is that refreshContactList fires when the function is called, rather than when it's used in the function.
I could get around it using eval(), but it's not the best practice, according to what I've read. How can I pass a function as a parameter in JavaScript?
You just need to remove the parenthesis:
addContact(entityId, refreshContactList);
This then passes the function without executing it first.
Here is an example:
function addContact(id, refreshCallback) {
refreshCallback();
// You can also pass arguments if you need to
// refreshCallback(id);
}
function refreshContactList() {
alert('Hello World');
}
addContact(1, refreshContactList);
If you want to pass a function, just reference it by name without the parentheses:
function foo(x) {
alert(x);
}
function bar(func) {
func("Hello World!");
}
//alerts "Hello World!"
bar(foo);
But sometimes you might want to pass a function with arguments included, but not have it called until the callback is invoked. To do this, when calling it, just wrap it in an anonymous function, like this:
function foo(x) {
alert(x);
}
function bar(func) {
func();
}
//alerts "Hello World!" (from within bar AFTER being passed)
bar(function(){ foo("Hello World!") });
If you prefer, you could also use the apply function and have a third parameter that is an array of the arguments, like such:
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"]);
Example 1:
funct("z", function (x) { return x; });
function funct(a, foo){
foo(a) // this will return a
}
Example 2:
function foodemo(value){
return 'hello '+value;
}
function funct(a, foo){
alert(foo(a));
}
//call funct
funct('world!',foodemo); //=> 'hello world!'
look at this
To pass the function as parameter, simply remove the brackets!
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);
The idea behind this is that a function is quite similar to a variable. Instead of writing
function ToBeCalled() { /* something */ }
you might as well write
var ToBeCalledVariable = function () { /* something */ }
There are minor differences between the two, but anyway - both of them are valid ways to define a function.
Now, if you define a function and explicitly assign it to a variable, it seems quite logical, that you can pass it as parameter to another function, and you don't need brackets:
anotherFunction(ToBeCalledVariable);
There is a phrase amongst JavaScript programmers: "Eval is Evil" so try to avoid it at all costs!
In addition to Steve Fenton's answer, you can also pass functions directly.
function addContact(entity, refreshFn) {
refreshFn();
}
function callAddContact() {
addContact("entity", function() { DoThis(); });
}
I chopped all my hair off with that issue. I couldn't make the examples above working, so I ended like :
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')");
And that's working like a charm ... for what I needed at least. Hope it might help some.
I suggest to put the parameters in an array, and then split them up using the .apply() function. So now we can easily pass a function with lots of parameters and execute it in a simple way.
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
You can also use eval() to do the same thing.
//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");
That's it. I was also looking for this solution and tried solutions provided in other answers but finally got it work from above example.
Here it's another approach :
function a(first,second)
{
return (second)(first);
}
a('Hello',function(e){alert(e+ ' world!');}); //=> Hello world
In fact, seems like a bit complicated, is not.
get method as a parameter:
function JS_method(_callBack) {
_callBack("called");
}
You can give as a parameter method:
JS_method(function (d) {
//Finally this will work.
alert(d)
});
The other answers do an excellent job describing what's going on, but one important "gotcha" is to make sure that whatever you pass through is indeed a reference to a function.
For instance, if you pass through a string instead of a function you'll get an error:
function function1(my_function_parameter){
my_function_parameter();
}
function function2(){
alert('Hello world');
}
function1(function2); //This will work
function1("function2"); //This breaks!
See JsFiddle
Some time when you need to deal with event handler so need to pass event too as an argument , most of the modern library like react, angular might need this.
I need to override OnSubmit function(function from third party library) with some custom validation on reactjs and I passed the function and event both like below
ORIGINALLY
<button className="img-submit" type="button" onClick=
{onSubmit}>Upload Image</button>
MADE A NEW FUNCTION upload and called passed onSubmit and event as arguments
<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);
}
By using ES6:
const invoke = (callback) => {
callback()
}
invoke(()=>{
console.log("Hello World");
})
If you can pass your whole function as string, this code may help you.
convertToFunc( "runThis('Micheal')" )
function convertToFunc( str) {
new Function( str )()
}
function runThis( name ){
console.log("Hello", name) // prints Hello Micheal
}
You can use a JSON as well to store and send JS functions.
Check the following:
var myJSON =
{
"myFunc1" : function (){
alert("a");
},
"myFunc2" : function (functionParameter){
functionParameter();
}
}
function main(){
myJSON.myFunc2(myJSON.myFunc1);
}
This will print 'a'.
The following has the same effect with the above:
var myFunc1 = function (){
alert('a');
}
var myFunc2 = function (functionParameter){
functionParameter();
}
function main(){
myFunc2(myFunc1);
}
Which is also has the same effect with the following:
function myFunc1(){
alert('a');
}
function myFunc2 (functionParameter){
functionParameter();
}
function main(){
myFunc2(myFunc1);
}
And a object paradigm using Class as object prototype:
function Class(){
this.myFunc1 = function(msg){
alert(msg);
}
this.myFunc2 = function(callBackParameter){
callBackParameter('message');
}
}
function main(){
var myClass = new Class();
myClass.myFunc2(myClass.myFunc1);
}
Related
TypeError: "listener" argument must be a function. Using npm pixelmatch in node JS [duplicate]
How do I pass a function as a parameter without the function executing in the "parent" function or using eval()? (Since I've read that it's insecure.) I have this: addContact(entityId, refreshContactList()); It works, but the problem is that refreshContactList fires when the function is called, rather than when it's used in the function. I could get around it using eval(), but it's not the best practice, according to what I've read. How can I pass a function as a parameter in JavaScript?
You just need to remove the parenthesis: addContact(entityId, refreshContactList); This then passes the function without executing it first. Here is an example: function addContact(id, refreshCallback) { refreshCallback(); // You can also pass arguments if you need to // refreshCallback(id); } function refreshContactList() { alert('Hello World'); } addContact(1, refreshContactList);
If you want to pass a function, just reference it by name without the parentheses: function foo(x) { alert(x); } function bar(func) { func("Hello World!"); } //alerts "Hello World!" bar(foo); But sometimes you might want to pass a function with arguments included, but not have it called until the callback is invoked. To do this, when calling it, just wrap it in an anonymous function, like this: function foo(x) { alert(x); } function bar(func) { func(); } //alerts "Hello World!" (from within bar AFTER being passed) bar(function(){ foo("Hello World!") }); If you prefer, you could also use the apply function and have a third parameter that is an array of the arguments, like such: 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"]);
Example 1: funct("z", function (x) { return x; }); function funct(a, foo){ foo(a) // this will return a } Example 2: function foodemo(value){ return 'hello '+value; } function funct(a, foo){ alert(foo(a)); } //call funct funct('world!',foodemo); //=> 'hello world!' look at this
To pass the function as parameter, simply remove the brackets! 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); The idea behind this is that a function is quite similar to a variable. Instead of writing function ToBeCalled() { /* something */ } you might as well write var ToBeCalledVariable = function () { /* something */ } There are minor differences between the two, but anyway - both of them are valid ways to define a function. Now, if you define a function and explicitly assign it to a variable, it seems quite logical, that you can pass it as parameter to another function, and you don't need brackets: anotherFunction(ToBeCalledVariable);
There is a phrase amongst JavaScript programmers: "Eval is Evil" so try to avoid it at all costs! In addition to Steve Fenton's answer, you can also pass functions directly. function addContact(entity, refreshFn) { refreshFn(); } function callAddContact() { addContact("entity", function() { DoThis(); }); }
I chopped all my hair off with that issue. I couldn't make the examples above working, so I ended like : 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')"); And that's working like a charm ... for what I needed at least. Hope it might help some.
I suggest to put the parameters in an array, and then split them up using the .apply() function. So now we can easily pass a function with lots of parameters and execute it in a simple way. 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
You can also use eval() to do the same thing. //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"); That's it. I was also looking for this solution and tried solutions provided in other answers but finally got it work from above example.
Here it's another approach : function a(first,second) { return (second)(first); } a('Hello',function(e){alert(e+ ' world!');}); //=> Hello world
In fact, seems like a bit complicated, is not. get method as a parameter: function JS_method(_callBack) { _callBack("called"); } You can give as a parameter method: JS_method(function (d) { //Finally this will work. alert(d) });
The other answers do an excellent job describing what's going on, but one important "gotcha" is to make sure that whatever you pass through is indeed a reference to a function. For instance, if you pass through a string instead of a function you'll get an error: function function1(my_function_parameter){ my_function_parameter(); } function function2(){ alert('Hello world'); } function1(function2); //This will work function1("function2"); //This breaks! See JsFiddle
Some time when you need to deal with event handler so need to pass event too as an argument , most of the modern library like react, angular might need this. I need to override OnSubmit function(function from third party library) with some custom validation on reactjs and I passed the function and event both like below ORIGINALLY <button className="img-submit" type="button" onClick= {onSubmit}>Upload Image</button> MADE A NEW FUNCTION upload and called passed onSubmit and event as arguments <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); }
By using ES6: const invoke = (callback) => { callback() } invoke(()=>{ console.log("Hello World"); })
If you can pass your whole function as string, this code may help you. convertToFunc( "runThis('Micheal')" ) function convertToFunc( str) { new Function( str )() } function runThis( name ){ console.log("Hello", name) // prints Hello Micheal }
You can use a JSON as well to store and send JS functions. Check the following: var myJSON = { "myFunc1" : function (){ alert("a"); }, "myFunc2" : function (functionParameter){ functionParameter(); } } function main(){ myJSON.myFunc2(myJSON.myFunc1); } This will print 'a'. The following has the same effect with the above: var myFunc1 = function (){ alert('a'); } var myFunc2 = function (functionParameter){ functionParameter(); } function main(){ myFunc2(myFunc1); } Which is also has the same effect with the following: function myFunc1(){ alert('a'); } function myFunc2 (functionParameter){ functionParameter(); } function main(){ myFunc2(myFunc1); } And a object paradigm using Class as object prototype: function Class(){ this.myFunc1 = function(msg){ alert(msg); } this.myFunc2 = function(callBackParameter){ callBackParameter('message'); } } function main(){ var myClass = new Class(); myClass.myFunc2(myClass.myFunc1); }
Passing along a function to a specific object
It's one of those times where I want to do soemthing, but I'm not sure what it's called... Hopefully, someone can help! I have the following function: function myfunction(object1, object2) { ... } I want to pass another function onto object1 specifically using the .click method. I can get this working easily with only one object within the function using the following: function myFunction(object1) { ... } $('button').click(function() { // Passes along another function! myFunction(anotherFunction()); }); How would someone approach this when there are 2 objects? I can't seem to get anything working. Any ideas? Or am I approaching this the wrong way?
Updated Answer Assuming still: function myFunction( function, anotherFunction, ... ) { ... } If you want to pass specific arguments but be able to omit arguments, you could provide an argument but catch it as falsy: myFunction( null, someOtherFunction, maybeAnotherFunction ) You then would need to handle the null, perhaps: function myFunction( function, anotherFunction, ... ) { let fnc = function; let fnc2 = anotherFunction; let ... = ...; if(fnc) ... if(fnc2) ... if(...) ... ... } Original Answer Because you are triggering the function immediately during its passing you might actually want to just send it without initializing it. Try the below and see if this works for you. function myFunction(object1, object2) { object1() object2() } $('button').click(function() { // Passes along another function! myFunction(anotherFunction1, anotherFunction2); });
var a = 5, b = 2; function check(val1, val2) { console.log(val1); console.log(val2); } function add() { return a + b; } function mulitply() { return a * b; } check(add, mulitply); // this will send refernce of function's not output check(add(), mulitply()); // this will converts into like this check(7,10);
Is it possible to determine whether a certain function may be called when a passed-in callback function is executed in JavaScript?
The question title basically says it all. I made this Fiddle to make it easy to test. Here's the code: var test = function(callback) { console.log("callback() might call alert()"); callback(); } test(function() { alert("one"); });
Converting a function to a string returns the source code, you can search that with a regular expression. var test = function(callback) { if (callback.toString().test(/\balert\s*\(/) { console.log("callback might call alert()"); callback(); }; This isn't perfect, though. It won't work with: var foo = alert; test(function() { foo("Fooled you!"); }); It could also get a false positive if alert( appears in a string.
You can redefine function alert function alert(str) { console.log('Somebody call alert:'+str); } But IMHO it can't be definitely checked before call.
Check for function called
Just wondering if there is anyway to fire some code when a function is called, without adding the code to the function, for example: function doSomething(){ //Do something } //Code to call when doSomething is called
You can wrap the function : (function(){ var oldFunction = doSomething; doSomething = function(){ // do something else oldFunction.apply(this, arguments); } })(); I use an IIFE here just to avoid polluting the global namespace, it's accessory.
Well, yes, it's not actually hard to do. The crucial thing is that a function's name is just an identifier like any other. You can redefine it if you want to. var oldFn = doSomething; doSomething = function() { // code to run before the old function return oldFn.apply(this, arguments); // code to run after the old function }; NB that it's better to do oldFn.apply(this, arguments) rather than just oldFn. In many cases it won't matter, but it's possible that the context (i.e. the value of this inside the function) and the arguments are important. Using apply means they are passed on as if oldFn had been called directly.
What about something like: function doSomething(){ doSomething.called = true; } //call? doSomething(); if(doSomething.called) { //Code to call when doSomething is called }
I know you said you don't want to modify the original function, but consider adding a callback. Then you can execute code based on different results in your function (such as onSucess and onError): function doSomething(onSuccess, onError){ try { throw "this is an error"; if(onSuccess) { onSuccess(); } } catch(err) { if(onError) { onError(err); } } } Then, when you call doSomething, you can specify what you want done with inline functions: doSomething(function() { console.log("doSomething() success"); }, function(err) { console.log("doSomething() error: " + err); });
Passing function with parameters as parameter of another function in JavaScript
I would like to pass a function with parameters to another function and have it run on an event, like this: var main_object = function () { this.main_function = function (function) { document.addEventListener('click',function); } this.passed_function = function (variable) { alert(variable); } } var main_object = new main_object(); main_object.main_function(main_object.passed_function(3));
In modern JavaScript engines, you can bind the function: mainObject.main_function(main_object.passed_function.bind(main_object, 3)); The first argument to bind will be this when the function executes and any remaining arguments to bind will be leading arguments in the call to the function.
If I understand you right, main_object.main_function(function() { main_object.passed_function(3) });
For what you're talking about, you could just use bind. In your case, you would do: main_object.main_function(main_object.passed_function.bind( main_object, 3 ));
function mainfunc(func) { alert(func); } function callBackFn(a) { alert(a); } mainfunc("arg1", callBackFn("javaScritFnParameter")); //call this in load For sure it works no need to worry... but callbackFn will execute first and next only "arg1" will execute.