Last active
April 4, 2021 00:43
-
-
Save svidgen/15d299fb9a8636f5f985cc6ad3c51a98 to your computer and use it in GitHub Desktop.
Function overloading in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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