Last Updated: February 25, 2016
·
2.687K
· elclanrs

Function overload in JavaScript

var __slice = [].slice;
var __toString = {}.toString;
var __noop = function(){};

function typeOf(x) {
  return __toString.call(x).slice(8,-1);
}

function overload(fs) {
  return function() {
    var types = __slice.call(arguments).map(typeOf);
    var f = fs[types.join('_')] || __noop;
    return f.apply(this, arguments);
  };
}

Usage:

var fn = overload({
  String: function greet(s) {
    return 'Hello '+ s;
  },
  Number: function square(x) {
    return x * x;
  },
  Array_Function: function map(xs, f) {
    return xs.map(f);
  },
  RegExp_String_Number: function replace(re, s, x) {
    return s.replace(re, x);
  }
});

fn('Joe'); //=> "Hello Joe"
fn(3); //=> 9
fn([1,2,3], function(x){ return x+1 }); //=> [2,3,4]
fn(/a/g, 'wawa', 2); //=> "w2w2"

3 Responses
Add your response

Excuse my ignorance, but what's the use case of this tip? Why would I do this?

over 1 year ago ·

It's useful in some cases. It's just a different pattern where you have a function that can take arguments of many types. For example the jQuery constructor could be done with overloading as it takes an element, an array, a pseudo-array, a jQuery collection, a string, etc... Here's a simple example:

var double = overload({
  String: function(x) {
    return x + x;
  },
  Number: function(x) {
    return x * 2;
  }
});

console.log(double('hey')); //=> heyhey
console.log(double(9)); //=> 18

You can use multiple if statements to check the type and the arguements object to count the arguments, but the typeof operator is not reliable and it'll end up looking ugly and difficult to understand; you'd have to write comments to clarify what you're checking. With overloading you solve this issue.

over 1 year ago ·

isn't this a bit poor performant?

over 1 year ago ·