JavaScript call_user_func_array
Call a user function which is the first parameter with the arguments contained in array
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2526 27 28 29 3031 | function call_user_func_array (cb, parameters) { // Call a user function which is the first parameter with the arguments contained in array // // version: 1008.1718 // discuss at: http://phpjs.org/functions/call_user_func_array // + original by: Thiago Mata (http://thiagomata.blog.com) // + revised by: Jon Hohle // + improved by: Brett Zamir (http://brett-zamir.me) // + improved by: Diplom@t (http://difane.com/) // + improved by: Brett Zamir (http://brett-zamir.me) // * example 1: call_user_func_array('isNaN', ['a']); // * returns 1: true // * example 2: call_user_func_array('isNaN', [1]); // * returns 2: false var func; if (typeof cb === 'string') { func = (typeof this[cb] === 'function') ? this[cb] : func = (new Function(null, 'return ' + cb))(); } else if (cb instanceof Array) { func = ( typeof cb[0] == 'string' ) ? eval(cb[0]+"['"+cb[1]+"']") : func = cb[0][cb[1]]; } else if (typeof cb === 'function') { func = cb; } if (typeof func !== 'function') { throw new Error(func + ' is not a valid function'); } return (typeof cb[0] === 'string') ? func.apply(eval(cb[0]), parameters) : ( typeof cb[0] !== 'object' ) ? func.apply(null, parameters) : func.apply(cb[0], parameters);} |
Examples
» Example 1
Running
1 | call_user_func_array('isNaN', ['a']); |
Should return
1 | true |
» Example 2
Running
1 | call_user_func_array('isNaN', [1]); |
Should return
1 | false |
Dependencies
No dependencies, you can use this function standalone.
Open syntax issues
php.js uses JsLint to help us keep our code consistent and prevent some common bugs.
Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.
Authors
Thanks to the following developers, you get to have call_user_func_array goodness in JavaScript.
Function didn't work for me when i've tried to call it like:
var ma = new A();
call_ser_func_array( array(ma, "foo"), [x] );
An error was thrown:
"Syntax error: Missing ] after element list" pointing on the line with eval.
I have modified the function like one below and it works now:
var func;
if (typeof cb == 'string') {
if (typeof this[cb] == 'function') {
func = this[cb];
} else {
func = (new Function(null, 'return ' + cb))();
}
} else if (cb instanceof Array) {
if ( typeof cb[0] == 'string' ) {
func = eval(cb[0]+"['"+cb[1]+"']");
} else {
func = cb[0][cb[1]];
}
}
if (typeof func != 'function') {
throw new Error(func + ' is not a valid function');
}
if ( typeof cb[0] == 'string' ) {
return func.apply(null, parameters);
} else {
return func.apply(cb[0], parameters);
}
@ Brett Zamir: Yes eval is evil so we'll try to minimize it's use as much as possible, I've made some minor adjustments, let me know if it's ok.
Hi,
First, here's a revision. I have a number of differences in mine, some perhaps for better or worse.
1) I can't see any need for the check "if (typeof this[func] == 'function') {"
2) Although 'eval' is not in vogue, I know, the Function constructor is also subject to eval() issues too, so I just used eval().
3) I didn't see any need for "throw new Exception(func + ' is not a valid function');" in the code posted here, since it would already be a function.
4) I allowed a PHP-style array to be given as the callback to supply a object+method (as in the call_user_func() PHP documentation)
[CODE="Javascript"]function call_user_func_array (cb, arr) {
if (typeof cb === 'string') {
cb = eval(cb);
}
else if (cb instanceof Array) {
cb = eval(cb[0]+"['"+cb[1]+"']");
}
cb.apply(null, arr);
}[/CODE]
And then, here's a new one, call_user_func():
[CODE="Javascript"]function call_user_func (cb) {
if (typeof cb === 'string') {
cb = eval(cb);
}
else if (cb instanceof Array) {
cb = eval(cb[0]+"['"+cb[1]+"']");
}
cb.apply(null, Array.prototype.slice.call(arguments, 1));
}[/CODE]
Works with objects, and regular functions, whether as strings, arrays, or functions.
Here is a cleaner version of call_user_func_array which uses Function:apply. It takes string arg functions or function objects. Because of scoping issues, however, this may behave differently then the method posted above:
call_user_func_array = function(func, parameters) {
if (typeof func == 'string') {
if (typeof this[func] == 'function') { func = this[func]; }
else {
func = (new Function(null, 'return ' + func))();
}
if (typeof func != 'function') {
throw new Exception(func + ' is not a valid function');
}
}
return func.apply(null, parameters);
}


Brett Zamir
Apr 28th