Skip to content

Instantly share code, notes, and snippets.

@svidgen
Last active April 4, 2021 00:43
Show Gist options
  • Save svidgen/15d299fb9a8636f5f985cc6ad3c51a98 to your computer and use it in GitHub Desktop.
Save svidgen/15d299fb9a8636f5f985cc6ad3c51a98 to your computer and use it in GitHub Desktop.
Function overloading in JavaScript
var overload = function(...overloads) {
const f = function(...args) {
let constructorArray = args.map(arg => arg.constructor);
let implIndex = f.overloads.findIndex(sig => {
return constructorArray.length === sig.length &&
constructorArray.every((o,i) => o === sig[i])
;
}) + 1;
if (implIndex > 0 && typeof(f.overloads[implIndex]) === 'function') {
return f.overloads[implIndex].apply({}, args);
} else {
const message = "There is no implementation that matches the provided arguments.";
console.error(message, constructorArray);
throw Error(message);
}
};
f.overloads = overloads;
return f;
};
let C = function(v) {
this.toString = () => String(v);
this.valueOf = () => String(v);
}
let log = overload(
[String], function(value) {
console.log('string', value);
},
[Number], function(value) {
console.log('number', value);
},
[String, Number], function(a, b) {
console.log('String and Number', a, b)
},
[Number, String], function(a, b) {
console.log('String and Number', a, b)
},
[C], function(a) {
console.log('C() found', a.toString())
},
[], function() {
console.log('void');
}
);
let c = new C('C object');
log(123);
log('abc');
log('abc', 123);
log(123, 'abc');
log(c);
log();
try {
log('abc', 'xyz');
console.error("Woops. This one should have failed!")
} catch (err) {
console.log("All good: An Error was successfully raised for non-existence implementation.")
}
// benchmarking
let normal = function(a,b) {
return a + b;
}
let overloaded = overload(
[Number, Number], function(a, b) {
return a + b;
}
);
var iterations = 1000000;
console.time('normal function call');
for (var i = 0; i < iterations; i++) {
normal(1,2);
}
console.timeEnd('normal function call');
console.time('overloaded function call');
for (var i = 0; i < iterations; i++) {
overloaded(1,2);
}
console.timeEnd('overloaded function call');
number 123
string abc
String and Number abc 123
String and Number 123 abc
C() found C object
void
[ERR] There is no implementation that matches the provided arguments. (2) [ƒ, ƒ]
All good: An Error was successfully raised for non-existence implementation.
normal function call: 8.364990234375 ms
overloaded function call: 126.35400390625 ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment