SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Enthusiast
    Join Date
    Sep 2009
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Crazy JavaScript Closure Question For Any Gurus Out there

    I'm currently reading about JavaScript closures and have come across an example in the book that is really bothering me. In all honesty, I'll probably never need to understand this example or at least not any time soon. But its just one of those annoying things that is going to keep me up at night thinking about it.

    Anyway, the book I'm reading below lists the following function that returns a function that invokes the function 'f' with the specified arguments and also any additional arguments that are passed to the returned function. (confused yet?)

    Code:
    function bindArguments(f /*, initial arguments */)
    {
      var boundArgs = arguments;
      return function() {
      
        var args = [];
        for(var i=1; i < boundArgs.length; i++) args.push(boundArgs[i]);
        for(var i=0; i < arguments.length; i++) args.push(arguments[i]);
    
        return f.apply(this,args); // why doesn't f(args) work here
    
      }
    }
    My issue is with why "f.apply(this,args)" works, but if I change it to "f(args)" it no longer works. I wrote the following code to test the function above, and sure enough it works as is but not if I change to "f(args)".

    Code:
    function count()
    {
    
      var total = 0;
      for(var i=0; i < arguments.length; i++) 
        total = total + arguments[i];
    
      return total;
    
    }
    
    var func = bindArguments(count,1,2);
    
    var sum = func(3,4);
    
    document.write("sum: " + sum + "<br/>");
    I understand what the apply method is - at least how to use it to call a regular function as a method of an object, but I can't understand its purpose here or why it fails without it. Any insights would be greatly appreciated.

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by anonymousdude View Post
    My issue is with why "f.apply(this,args)" works, but if I change it to "f(args)" it no longer works. I wrote the following code to test the function above, and sure enough it works as is but not if I change to "f(args)"
    It's all about how the arguments of the function are affected.

    With args being an array of values, such as:
    array(1, 2)

    When you call f(args) it's equivalent to calling

    Code javascript:
    f(array(1, 2))

    using the f.apply(this, args) method causes the contents of the array to be passed instead:

    Code javascript:
    f(1, 2)

    which is the result that you're after.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Enthusiast
    Join Date
    Sep 2009
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post
    It's all about how the arguments of the function are affected.

    With args being an array of values, such as:
    array(1, 2)

    When you call f(args) it's equivalent to calling

    Code javascript:
    f(array(1, 2))

    using the f.apply(this, args) method causes the contents of the array to be passed instead:

    Code javascript:
    f(1, 2)

    which is the result that you're after.
    And of course it would be something so incredibly simple. Thanks for posting. Makes perfect sense now.

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by anonymousdude View Post
    And of course it would be something so incredibly simple. Thanks for posting. Makes perfect sense now.
    TBH it took me a while to get my head around the answer, and then some more to simplify the explanation right down. See the JavaScript Closures for a not-so-simple explanation.

    Thank you for saying that my answer is incredibly simple, for that's high-praise indeed.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    SitePoint Enthusiast
    Join Date
    Sep 2009
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post
    TBH it took me a while to get my head around the answer, and then some more to simplify the explanation right down. See the JavaScript Closures for a not-so-simple explanation.

    Thank you for saying that my answer is incredibly simple, for that's high-praise indeed.
    I was forgetting the difference between the JavaScript call() and apply() methods and that apply takes an array as it second parameter. Once you pointed out that args was an array it made perfect sense.

    It's funny how when I'm learning something new and confusing (closures) and run into an issue, I assume the answer will be something equally new and confusing and not something as simple as forgetting what type of arguments I'm passing to a function. I was actually thinking it had something to do with the first parameter to apply 'this', even though I knew 'this' was only referring to the global object.

    Thanks again.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •