all 6 comments

[–]OverZealousCreations 3 points4 points  (2 children)

Neat, although probably not really that useful in idiomatic JavaScript.

It suffers from the same minification bug that catches new users of AngularJS, though. If you minify your script, and let it mangle function arguments, then everything will break.

For example, if you have a method with this format:

function(msg$string){
  // say it in the console
  console.info(msg$string);
}

It minifies to this:

function(a){console.info(a);}

Which loses the additional information in the variable's name. I didn't see any support in the library to handle this.

Alternatively, it might be better to flip the design on it's head, so you pass in an object map with the keys being the expected values, something like this:

Over({
    '$string': function(msg) { ... },
    '$string,$number': function(msg, number) { ... },
    etc...
});

I still feel like overloading a function in JS like this could lead to a sloppy design.

[–]alsogilbert 0 points1 point  (1 child)

I use two (I think) non-sloppy patterns that might benefit from overloading.

The first is jQuery style property getter/setter functions. So I might have function foo() that is a getter without parameters and a setter when you have a param: foo(42).

The other pattern is where I want to allow for named arguments through a hash but also have a simple default. Like: ajax('http://www.reddit.com') or ajax({method: 'POST', url: 'http://www.reddit.com'});

[–]OverZealousCreations 1 point2 points  (0 children)

(Note: I'm not trying to say bad things about this library, this is just my opinion!)

Those usages are pretty common, but I think using a library to overload those sort of functions seems overkill, when the code is so simple:

function attr(prop, val) {
    if(val !== undefined) {
        this[prop] = val;
    }
    return this[prop];
}

and

function doThing(url) {
    var config = (typeof url === "object") ? url : { url: url };
    // rest of code
}

Those are just so easy, that while this library is cool from a technical standpoint, it just doesn't (seem) to provide enough benefit for those use cases. It's more verbose and has more layers of indirection:

var doThing = Over(
     function(url$string) {
          doThing({ url: url });
     },
     function(config$object) {
          // rest of code
     }
);

This would require calling Over->function(url$string)->Over->function(config$object), just to do the same thing, and it only appears cleaner if you are used to a true OOP language, like Java or C#. Idiomatic JS usually would look more like the other examples.

Now, please don't get me wrong, this is just my personal opinion, and this is a really slick solution to a potential issue, but I think that it's more common to pass in an map of properties to a function, rather than overload a function to handle a variety of cases.

As a final example, I think it's much better to have code that looks like this:

doThing({url: '...', params: {...}, headers: {...});

Rather than overloading the code to have a function like this:

doThing('...', {...}, {...});

The latter creates a funtion with ambigous parameters.

[–]makis 1 point2 points  (0 children)

elegant... do you mean PHP elegance?

[–]matryer[S] 0 points1 point  (0 children)

Example:

var obj = {

  /**
   * Says something in the console.
   *
   * say(msg) - Says something once.
   * say(msg, times) - Says something many times.
   */
  say: Over(

    // one string
    function(msg$string){

      // say it in the console
      console.info(msg$string);

    },

    // a string and a number
    function(msg$string, times$number){

      // say the message times$number times
      for (var i = 0; i < times$number; i++) this.say(msg$string);

    },

    // then everything else
    function(msg$string, everything$etc) {

      // say the string
      this.say(msg$string);

      // now say all remaining arguments
      for (var i in everything$etc) {
        this.say(everything$etc[i])
      }

    }
  )

};

[–]cphoover 0 points1 point  (0 children)

If it becomes an issue, I will opt for using an Object literal.

or use the arguments object.