InaMastabba InaMastabba - 4 months ago 13
Javascript Question

Re: A JavaScript Fn that accepts unknown # args - call Fn wrks - call via var does not

Learning how to write JS Fn that accepts an unknown number of arguments.

function foo(a,b,c,d){
//do something
//return something
}

var bar = function () {
var arg = Array.from(arguments);
var lastIndx = arg.length;
var parArray = arg.slice(1,lastIndx);
var argMnts = arguments[0];
return arguments[0].apply(this, parArray);
};


calling bar thus works:

bar(foo,1,4,3,7);


calling it like so:

var tester = bar(foo,1,4,3,7);
tester();


results in: tester is not a function

From my research I suspected it might have to do with the scope of "this" or arguments so I assigned their values to variables, subbed the vars, and the result was the same.

Some insight would be immensely appreciated.

Answer

In your example, calling bar() returns whatever the results of calling foo(...) is. So, if you want to be able to do this:

var tester = bar(foo,1,4,3,7);
tester();

Then, foo(...) has to return another function that can get assigned to tester and can then get called again.


If, instead of the way it is above, if you don't want bar(foo, ...) to actually call foo(), but want it to return a function that will then call foo() with the appropriate arguments, you can change bar() to this:

var bar = function () {
    var args = Array.from(arguments);
    var fn = args.shift();
    var self = this;
    return function() {
        return fn.apply(self, args);
    }
};

var tester = bar(foo,1,4,3,7);
tester();

Here, bar() returns a function, that (when called) will call foo().


Or, with the right ES6 support, you could use rest parameters;

var bar = function (fn, ...args) {
    var self = this;
    return function() {
        return fn.apply(self, args);
    }
};

or, you could use .bind() with rest parameters and the spread operator:

var bar = function (fn, ...args) {
    return fn.bind(this, ...args);
};