1

I want to write a function that takes a function and some other objects as arguments and makes these arguments as default arguments for the function and returns a new function.

assume we have drawRect(x, y, x2, y2) I want to write a function named 'partial' so that

(partial(drawRect, 0, 0))(x2, y2);

be equal to

drawRect(0, 0, x2, y2);

please note that I want to function partial be flexible so it takes any function and any number of arguments.

so far I've written this:

function temp(a, b, c, d){
  document.write(a + b + c + d);
}

function partial(func){
  var arr = new Array();
  for (var i = 0; i<arguments.length; i++){
    arr.push(arguments[i+1]);
  }

  var tf = function(){f.apply(this, arr.concat(func.arguments))}
  console.log(2);
  return tf;
}

var ff = partial(temp, 44, 55);
ff(20, 30); 

but it writes a 'Nan' on document. I need to access to function 'ff' arguments when calling but I've no idea how to do it. Can you guys please help me solving this?

Alireza Farahani
  • 2,238
  • 3
  • 30
  • 54
  • 1
    This is called [currying](http://javascript.crockford.com/www_svendtofte_com/code/curried_javascript/index.html). – Evan Davis Nov 21 '13 at 20:07
  • Well it's *like* currying, but strictly speaking it's different because JavaScript is not a lazy-evaluation language. (I'm not 100% sure who's in charge of the terminology; I understand the difference but I don't know who cares how the term is used :) – Pointy Nov 21 '13 at 20:14

2 Answers2

2

There seemed to be a lot of unncessary testing code in there, which I've cleaned up. To my understanding, the code below and this demo do what you required.

function temp(a, b, c, d){
  console.log(a + b + c + d);
}

function partial(f){
    var defaultArgs = Array.prototype.slice.call(arguments, 1);
    var that = this;

    var tf = function(){
        f.apply(that, defaultArgs.concat(Array.prototype.slice.call(arguments)));
    }
    return tf;
}

var ff = partial(temp, 44, 55);
ff(20, 30);

// console output: 149
Asad Saeeduddin
  • 46,193
  • 6
  • 90
  • 139
  • 1
    @alireza I am simultaneously converting the `arguments` object into an array and excluding the first element from it. In terms of your original code, this would be equivalent to calling `arr.slice(1)`, which would retrieve the entirety of `arr` starting with the second element. – Asad Saeeduddin Nov 21 '13 at 20:32
2

You can do it with .bind()

function partial(f, x, y) {
  return f.bind(this, x, y);
}
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • +1, didn't know about this. Are bound functions just a regular function with different logic, or are they distinct in some way? – Asad Saeeduddin Nov 21 '13 at 20:15
  • They're "regular functions", but they're constructed in a particular way. It's not really that much different than the other answer(s) here in most cases. [The MDN page goes into details.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) – Pointy Nov 21 '13 at 20:18