2

This is my lazy loader for functions:

var make_lazy = function (calledFunc, a, b, c, d, e, f) {
    return function () {
        return calledFunc(a, b, c, d, e, f)
    }
};

It works with most functions except this one:

function superAdd() {
    return Array.prototype.slice.apply(arguments).reduce(function (a, c) {
        return a + c;
    }, 0);
}

How do I modify this function to accept a variable number of arguments? I tried using the arguments object with no success.

3
  • 2
    Where are you calling superAdd? Can you show a complete example of the implementation that's not working? Commented Oct 6, 2015 at 19:09
  • @Josh Beam I'm using a unit test var lazy_value = make_lazy(superAdd, 3, 5); Test.expect(lazy_value() === 15, 'Evaluates the expression when required'); Commented Oct 6, 2015 at 19:13
  • function make_lazy(fn, args) {return Function.apply.bind(fn, this, args);}; Commented Oct 6, 2015 at 19:35

3 Answers 3

1
/**
 * @param args {Array}
 */
var make_lazy = function(calledFunc, args) {
  return function () {
    return calledFunc.apply(this, args);
  }
};

var lazy = make_lazy(superAdd, [3, 5]);

lazy(); // => 8

With the above, you can just group your indeterministic amount of arguments into an array.

The way the above works is because you have a variable number of arguments, only after the first argument (which is deterministic).

With ES6, it's even cooler, using the spread operator:

function make_lazy(calledFunc, ...args) {
  return () => calledFunc(...args);
}
Sign up to request clarification or add additional context in comments.

Comments

1

use arguments along with .apply on the callback function like you are doing for the slice function

var make_lazy = function (calledFunc) {
    return function () {
       return calledFunc.apply(null,arguments);
    }
};

function one(a){
   console.log("how many args: "+arguments.length,a);
}
function two(a,b){
   console.log("how many args: "+arguments.length,a,b);
}
function three(a,b,c){
   console.log("how many args: "+arguments.length,a,b,c);
}

var onelazy = make_lazy(one);
var twolazy = make_lazy(two);
var threelazy = make_lazy(three);
onelazy(1);
twolazy(1,2);
threelazy(1,2,3);

Or if you are wanting to pass predefined values as arguments, just get the arguments from within the make_lazy function itself (less the first argument), and use that for the apply call.

var make_lazy = function (calledFunc) {
    var args = [].splice.call(arguments,1);
    return function () {
       return calledFunc.apply(null,args);
    }
};
function two(a,b){
   console.log("Num Args: "+arguments.length,a,b);
}
var twoLazy = make_lazy(two,3,5);
twoLazy();

Comments

1

I'm assuming the problem you are having with the arguments version of the make_lazy function is that you are using the wrong arguments list, such as:

    var make_lazy = function (calledFunc) {
      return function () {
        return calledFunc.apply(null, arguments);
      };
    };

the arguments in that statement references the returned function's arguments, such that

    var lazy = make_lazy(superAdd, 1, 2, 3);
    lazy(3,4,5);
    // returns 12 -not- 6

because it is only taking in the arguments that are applied at lazy's execution. The make_lazy function should store the arguments at its run time so that it can use it later.

So to answer your question, store arguments as a variable outside of the scope of the inner returned function:

    var make_lazy = function (calledFunc) {

      // Remove the calledFunc from the arguments list by passing in `1` to slice.
      var lazyArgs = Array.prototype.slice.call(arguments, 1);

      return function () {
        return calledFunc.apply(null, lazyArgs);
      };
    };

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.