henrybai henrybai - 1 year ago 79
Javascript Question

javascript and currying

I am reading through John Resig's Secrets of Javascript ninja and was trying out one of the examples on currying and parital functions. The code is as follows:

<button id="test">Click Me!</button>

<script type="text/javascript">
Function.prototype.curry = function() {
var fn = this,
args = Array.prototype.slice.call(arguments);

return function() {
return fn.apply(this, args.concat(

var elem = document.getElementById("test");
var bindClick = elem.addEventListener.curry("click");
bindClick(function(){ console.log("OK"); });

However, the following code seems to generate an error Uncaught TypeError: Illegal invocation on the apply function.

I cant seem to figure out the reason as it all seems to make sense.
will return an anonymous function that calls the function
as the function context (
) and the arguments will be
["click", function() {console.log("OK"); }]

Answer Source

The problem is that you've lost the context of the element. The addEventListener method has to be called on an element, but you're calling it on a function:

// Here, `this` refers to a function, not an element
return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));

You would need to pass in the element to your new function. For example:

Function.prototype.curry = function () {
    var fn = this,
    args = Array.prototype.slice.call(arguments);

     return function (context) {
         return fn.apply(
             args.concat(Array.prototype.slice.call(arguments, 1))

Here's a working example. Notice the addition of a context argument to the returned function, and also notice the addition of the second argument to the slice call - that's needed to remove the new context argument and only apply any following arguments.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download