Folgender Code implementiert Mehrfachdispatch in JavaScript (ECMAScript 5, um genau zu sein). Ich habe ihn unter die MIT-Lizenz gestellt, und er kann als mulkiple-dispatch.js heruntergeladen werden.
Implementierung
"use strict"; function MulkipleDispatchObject(prototype, slots) { var inheritsFrom = function(object, other) { return (object !== null && (object === other || inheritsFrom(Object.getPrototypeOf(object), other))); }; var realSlots = {}; for (var slot in slots) { if (!(slots[slot] instanceof Array)) { realSlots[slot] = slots[slot]; } else { (function(slot) { var mulkiSlot = { method: true, value: function() { for (var alternative in slots[slot]) { var applies = true; alternative = slots[slot][alternative]; var typelist = alternative['dispatch']; for (var i = 0; i in typelist && i in arguments; i++) { if (!(arguments[i] === null || arguments[i] instanceof typelist[i] || inheritsFrom(arguments[i], typelist[i]))) { applies = false; break; } } if (applies) { return alternative['value'].apply(this, arguments); } } return Object.getPrototypeOf(this)[slot].apply(this, arguments); }}; realSlots[slot] = mulkiSlot; })(slot); } } return Object.create(prototype, realSlots); } MulkipleDispatchObject.create = MulkipleDispatchObject;
Beispiel
Verwendet wird der Code zum Beispiel wie folgt (hier mit dem printf
-Modul von Narwhal):
var printf = require('printf'); // ----- Konstruktoren ----- function Being(name) { return MulkipleDispatchObject.create(Being.prototype, { name: { value: name, enumerable: true }, toString: { method: true, value: function() { return printf.sprintf("%s", this.name); }}, greet: [{ dispatch: [], value: function(other) { printf.printf("%s grüßt %s.", this, other); }}] }); } function Person(name) { return MulkipleDispatchObject.create(Person.prototype, { name: { value: name, enumerable: true }, greet: [ { dispatch: [Person], value: function(other) { printf.printf("%s sagt: \"Mulk, %s\".", this, other.name); }}, { dispatch: [Cat], value: function(other) { printf.printf("%s streichelt %s.", this, other); }}] }); } Person.prototype = Being(null, null); Person.prototype.constructor = Person; function Cat(name, owner) { return MulkipleDispatchObject.create(Cat.prototype, { name: { value: name, enumerable: true }, owner: { value: owner, enumerable: true, modifiable: true }, greet: [{ dispatch: [], value: function(other) { printf.printf("%s miaut %s an.", this, other); }}] }); } Cat.prototype = Being(null, null); Cat.prototype.constructor = Cat; // ----- Hauptprogramm ----- var matthias = Person("Matthias"); var simon = Person("Simon"); var magdalena = Person("Magdalena"); var mauzi = Cat("Mauzi", magdalena); matthias.greet(magdalena); // => Matthias sagt: "Mulk, Magdalena". magdalena.greet(matthias); // => Magdalena sagt: "Mulk, Matthias". simon.greet(matthias); // => Simon sagt: "Mulk, Matthias". matthias.greet(simon); // => Matthias sagt: "Mulk, Simon". mauzi.greet(matthias); // => Mauzi miaut Matthias an. matthias.greet(mauzi); // => Matthias streichelt Mauzi.
Anmerkungen
Die Implementierung ist sehr naiv, und entsprechend unterwältigend wird vermutlich die Performance sein. Es gibt momentan außerdem keine Möglichkeit, nachträglich Mehrfachmethoden hinzuzufügen.
Comments
Submit a comment
Note: This website uses a JavaScript-based spam prevention system. Please enable JavaScript in your browser to post comments. Comment format is plain text. Use blank lines to separate paragraphs.