Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    Regular Coder
    Join Date
    Sep 2008
    Posts
    205
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Question Better to pass a function or method as an argument?

    I have a function, which currently takes a method as an argument. Is it good, inconsequential, or bad to use a method rather than a function as an argument?

    Following, for simplicity's sake, is short generic example of both the function and method versions:
    Code:
    function example(string, test){
    test(string);
    }
    
    example("Hello", function(text){document.write(text);})
    Code:
    function example2(string, obj){
    obj.test(string);
    }
    
    example2("Hello", { test : function(text){ document.write(text); } })
    Last edited by Dan06; 07-17-2009 at 07:37 PM.

  • #2
    jkd
    jkd is offline
    Senior Coder jkd's Avatar
    Join Date
    May 2002
    Location
    metro DC
    Posts
    3,163
    Thanks
    1
    Thanked 18 Times in 18 Posts
    If the object exists solely to package the function in as a method (no real distinction between the two in javascript), then it is wasteful. Just pass the function directly.

  • #3
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,296
    Thanks
    10
    Thanked 584 Times in 565 Posts
    Quote Originally Posted by jkd View Post
    If the object exists solely to package the function in as a method (no real distinction between the two in javascript), then it is wasteful.
    methods have a different "this" than do functions, which get "window" or a called/applied-specific "this".

    in the trivial example, it doesn't much matter.
    methods share "this", so a more complicated version of {test} could use something like document.write(this.format(text)); , where format is another method on the same object.

    like i said, not very useful for simple examples, but as complexity increases, methods provided the advantage of being iterable and contained in a single namespace, which can make them easier to find and use.

    methods also provide two distinct function references: the method path/name, and an optional function name that can only be reached inside the method itself.
    the path refers to the function object and the private name refers to an instance of that object, aka arguments.callee.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • #4
    Regular Coder
    Join Date
    Sep 2008
    Posts
    205
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Thanks for the insight/feedback. The function at the source of my question is an AJAX function, to which I was passing a (callback) method. For the most part the callbacks were simple, so I was curious should I convert the AJAX function to use functions as arguments rather than methods. But, with the possibility of my callbacks becoming more complex, I chose to keep the AJAX function as is - i.e. accepting methods as arguments.

  • #5
    jkd
    jkd is offline
    Senior Coder jkd's Avatar
    Join Date
    May 2002
    Location
    metro DC
    Posts
    3,163
    Thanks
    1
    Thanked 18 Times in 18 Posts
    Quote Originally Posted by rnd me View Post
    methods have a different "this" than do functions, which get "window" or a called/applied-specific "this".
    Still no distinction. Recall that the global object (in a browser context) is window. So it is only natural that unprefixed function calls default to window, since of course, that *is* the implied prefix.

    in the trivial example, it doesn't much matter.
    methods share "this", so a more complicated version of {test} could use something like document.write(this.format(text)); , where format is another method on the same object.
    Dynamic dispatch. It's a wonderful thing.

  • #6
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    Not to sound nitpicky, but strictly speaking you can't pass methods around. In short, a method in Javascript is a function that only gains 'method-status' on application from an object.

    Code:
    var x = {
      f: function () {
        return this;
      }
    };
    
    g = x.f; // g does not inherit x as this
    
    // executed in Firefox
    alert (g ()); // [object Window]
    alert (x.f ()); // [object Object]
    alert ((x.f) ()); // [object Object]... kind of surprised me
    So what you are considering is whether or not to pass an object or a function (... yes, these are objects too) to your function.

    The issue with passing an object is that you need to know the method name beforehand and settle on it. Not very malleable. In your example, you are stuck with using xxxx.test. Personally, I dislike that. An improvement perhaps is to pass the attribute name:
    Code:
    function example3 (string, obj, meth) {
      obj [meth] (string);
    }
    
    var obj = { test : function (text) { document.write (text); } };
    example3 ("Hello", obj, "test");
    I don't like this either.

    I do, however, love passing functions around. After all, Javascript does have first-class functions. Not only does this allow you to pass them around, but you can have nested functions. Fun! Just be careful about memory leaks that occur in crappy browsers (Internet Explorer ) and DOM objects.

    If you feel like an object is needed... well, this approach supports that too! Wrap the method call in a function!
    Code:
    Function.bundle = function (context, f, args) {
      if (typeof f == "string" && context)
        f = context [f];
      if (arguments.length < 3)
        args = [];
      else if ( !(args instanceof Array))
        args = Array.prototype.slice.call (arguments, 2);
      return function () {
        return f.apply (context, args);
      };
    };
    
    function example (string, test) {
      test (string);
    }
    
    var obj = { test : function (text) { document.write (text); } };
    example ("Hello", Function.bundle (obj, "test"));
    Last edited by Trinithis; 07-19-2009 at 05:00 AM.
    Trinithis


  •  

    Posting Permissions

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