Skip to content

Instantly share code, notes, and snippets.

@leeferwagen
Last active August 29, 2015 14:03
Show Gist options
  • Save leeferwagen/7368e398bd48043873e3 to your computer and use it in GitHub Desktop.
Save leeferwagen/7368e398bd48043873e3 to your computer and use it in GitHub Desktop.
Function for overloading class methods in JavaScript
(function() {
'use strict';
var global;
if (typeof window == 'object') {
global = window;
} else if (typeof exports == 'object') {
global = exports;
}
var trim = Function.prototype.call.bind(String.prototype.trim);
var tokenizeSignatur = function(signatur) {
var m = signatur.match(/^(.*?)\s*\((.*?)\)$/);
if (m === null) {
throw new Error('Invalid method signatur: ' + signatur);
}
var name = m[1];
var args = m[2].split(',').map(trim);
return {
name: name,
args: args
};
};
var getArgumentType = function(arg) {
if (arg === undefined) return 'undefined';
if (arg === null) return 'null';
return arg.constructor.name;
};
global.overloading = function Overloading(prototype, methods) {
for (var signatur in methods) {
var method = methods[signatur];
var token = tokenizeSignatur(signatur);
if ('undefined' == typeof prototype[token.name]) {
Object.defineProperty(prototype, token.name, {
enumerable: false,
configurable: false,
writeable: false,
value: function() {
var argumentTypes = [];
for (var i = 0; i < arguments.length; i++) {
argumentTypes.push(getArgumentType(arguments[i]));
}
var signatur = token.name + '(' + argumentTypes.join(',') + ')';
if ('function' != typeof this[signatur]) {
throw new Error('Undefined method signatur: ' + signatur);
}
this[signatur].apply(this, arguments);
}
});
}
Object.defineProperty(prototype, signatur, {
enumerable: false,
configurable: false,
writeable: false,
value: method
});
}
};
}())
@leeferwagen
Copy link
Author

Usage example

http://jsfiddle.net/MuslimIdris/nx64R/

Create a class „User“ with only one method in 3 variations

function User() {
  this.name = '';
  this.age = 0;
}

overloading(User.prototype, {
  'set(String,Number)': function(name, age) {
    this.set(name);
    this.set(age);
  },
  'set(String)': function(name) {
    this.name = name;
  },
  'set(Number)': function(age) {
    this.age = age;
  }
});

And now use the sample class

var user = new User;

user.set('foo', 33);
console.log('Name(%s) Age(%s)', user.name, user.age); // Name(foo) Age(33)

user.set('bar');
console.log('Name(%s) Age(%s)', user.name, user.age); // Name(bar) Age(33)

user.set(44);
console.log('Name(%s) Age(%s)', user.name, user.age); // Name(bar) Age(44)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment