The following function will return an array of the parameter names of any function passed in.
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
function getParamNames(func) {
var fnStr = func.toString().replace(STRIP_COMMENTS, '');
var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
if(result === null)
result = [];
return result;
}
Example usage:
getParamNames(getParamNames) // returns ['func']
getParamNames(function (a,b,c,d){}) // returns ['a','b','c','d']
getParamNames(function (a,/*b,c,*/d){}) // returns ['a','d']
getParamNames(function (){}) // returns []
Edit:
With the invent of ES6 this function can be tripped up by default parameters. Here is a quick hack which should work in most cases:
var STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,\)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,\)]*))/mg;
I say most cases because there are some things that will trip it up
function (a=4*(5/3), b) {} // returns ['a']
Edit: I also note vikasde wants the parameter values in an array also. This is already provided in a local variable named arguments.
excerpt from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments:
The arguments object is not an Array. It is similar to an Array, but does not have any Array properties except length. For example, it does not have the pop method. However it can be converted to a real Array:
var args = Array.prototype.slice.call(arguments);
If Array generics are available, one can use the following instead:
var args = Array.slice(arguments);
Answer from Jack Allan on Stack OverflowThe following function will return an array of the parameter names of any function passed in.
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
function getParamNames(func) {
var fnStr = func.toString().replace(STRIP_COMMENTS, '');
var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
if(result === null)
result = [];
return result;
}
Example usage:
getParamNames(getParamNames) // returns ['func']
getParamNames(function (a,b,c,d){}) // returns ['a','b','c','d']
getParamNames(function (a,/*b,c,*/d){}) // returns ['a','d']
getParamNames(function (){}) // returns []
Edit:
With the invent of ES6 this function can be tripped up by default parameters. Here is a quick hack which should work in most cases:
var STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,\)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,\)]*))/mg;
I say most cases because there are some things that will trip it up
function (a=4*(5/3), b) {} // returns ['a']
Edit: I also note vikasde wants the parameter values in an array also. This is already provided in a local variable named arguments.
excerpt from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments:
The arguments object is not an Array. It is similar to an Array, but does not have any Array properties except length. For example, it does not have the pop method. However it can be converted to a real Array:
var args = Array.prototype.slice.call(arguments);
If Array generics are available, one can use the following instead:
var args = Array.slice(arguments);
Below is the code taken from AngularJS which uses the technique for its dependency injection mechanism.
And here is an explanation of it taken from http://docs.angularjs.org/tutorial/step_05
Angular's dependency injector provides services to your controller when the controller is being constructed. The dependency injector also takes care of creating any transitive dependencies the service may have (services often depend upon other services).
Note that the names of arguments are significant, because the injector uses these to look up the dependencies.
/**
* @ngdoc overview
* @name AUTO
* @description
*
* Implicit module which gets automatically added to each {@link AUTO.$injector $injector}.
*/
var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(.+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
function annotate(fn) {
var $inject,
fnText,
argDecl,
last;
if (typeof fn == 'function') {
if (!($inject = fn.$inject)) {
$inject = [];
fnText = fn.toString().replace(STRIP_COMMENTS, '');
argDecl = fnText.match(FN_ARGS);
forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
arg.replace(FN_ARG, function(all, underscore, name){
$inject.push(name);
});
});
fn.$inject = $inject;
}
} else if (isArray(fn)) {
last = fn.length - 1;
assertArgFn(fn[last], 'fn')
$inject = fn.slice(0, last);
} else {
assertArgFn(fn, 'fn', true);
}
return $inject;
}
Videos
What is the rest parameter in JavaScript?
What are default parameters in JavaScript?
Can I destructure objects in function parameters?
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);
You can also pass anonymous functions:
function addContact(id, refreshCallback) {
refreshCallback();
// You can also pass arguments if you need to
// refreshCallback(id);
}
addContact(1, () => alert('hello world'));
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"]);
$("a").click(function(event){
event.preventDefault();
});
The parameter you are passing to the function click is, itself a function. It looks like this:
function(event){
event.preventDefault();
}
So event is the parameter that will be passed to that function by whatever calls that function. What calls that function is jQuery, when a click event happens on the targeted element(s).
If you look at the documentation for click you'll see this:
.click( handler )
handler
Type: Function( Event eventObject ) A function to execute each time the event is triggered.
So your function that you are passing is handler. Handler is a function that takes an eventObject (which you called simply event, which is fine - it doesn't matter here) argument of the type Event
So simply put, you don't need to worry about how that function gets called. The library will call it at the appropriate time and pass the appropriate object as event to that function. All you need to worry about is what to do in that handler which may or may not involve actually using event.
It might be confusing you that the function you are passing to click is anonymous. It doesn't have a name. If it helps, you can do this:
function MyClickHander(event) {
// do something here
}
$("a").click(MyClickHandler);
Which is essentially the same. But people often prefer to use anonymous functions rather than write potentially dozens of named handler functions for all the various events they might need to worry about.
EDIT:
It might help to also think about how you might write a function that took a function as a parameter (e.g. a function that takes a callback):
function Foo(callback) {
bar = someValue;
callback(bar);
}
Which you might use like this:
Foo(function(bar) {
console.log(bar);
});
So here bar comes from inside Foo - just like event comes from inside click. You don't have to worry about exactly where in click event comes from (although you can dig through the source code if you are really so inclined), the jQuery documentation tells you what click will do with your handler so you don't have to.
Functions are first class citizens in javascript. So you can pass them around and assign them to variables. Don't think of them as control structures, but as things themselves. In the case of your click listener, the argument you are passing actually IS the function. You are telling the jQuery library "here is a function I want you to call whenever a click happens." And the jQuery documentation promises that, at the time it calls your function, it will call it with an argument of event.
Maybe it helps you to see the code this way:
var callMeOnClick = function(event){
console.log(event);
};//nothing has happened yet. The function is being assigned to a variable, not invoked.
$("a").click(callMeOnClick);//giving the function to jQuery to execute later.
I think I understand the question you are asking, I'm just not sure how to explain it best. I hope that helps somewhat though.