Skip to content

Instantly share code, notes, and snippets.

@vstarck
Last active December 14, 2015 08:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vstarck/5057479 to your computer and use it in GitHub Desktop.
Save vstarck/5057479 to your computer and use it in GitHub Desktop.
Implementing High Order Messaging using ES6 proxies.
var plainObjects = new ForwardingList({}, {}, {});
plainObjects.set.prop(1);
plainObjects.set.foo('bar');
plainObjects[0].prop; // 1
plainObjects[2].foo; // "bar"
// Dummy constructor
function $Element() {
this.visible = false;
this.show = function () { this.visible = true }
this.hide = function () { this.visible = false }
this.isVisible = function () { return this.visible }
this._html = '';
this.html = function (html) {
this._html = html
};
}
var $elements = new ForwardingList(new $Element);
// Forward the show message to each member
$elements.each.show();
$elements[0].isVisible(); // true
$elements.each.hide();
$elements[0].isVisible(); // false
// Forward the html message to each member (with the 'Hello world' argument)
$elements.each.html('Hello world');
$elements[0]._html; // "Hello world"
var ForwardingList = (function () {
var proto = {
constructor:ForwardingList,
size:function () {
return this._array.length;
},
toString:function () {
return 'ForwardingList[' + this._array.toString() + ']';
}
};
// High Order Methods
var HOM = {
set:function (property, value) {
this.forEach(function (current) {
current[property] = value;
});
return this;
},
each:function (method) {
var args = [].slice.call(arguments, 1);
this.forEach(function (current) {
current[method].apply(current, args);
});
return this;
}
};
function isHOM(name) {
return Object.keys(HOM).indexOf(name) !== -1;
}
function makeHOM(target, hom) {
return new Proxy({}, {
get:function (_, name) {
return function () {
var args = [].slice.call(arguments);
args.unshift(name);
return HOM[hom].apply(target, args);
}
}
});
}
return function () {
var target, handler, proxy;
target = Object.create(proto);
target._array = [].slice.call(arguments);
handler = {
get:function (target, name) {
// Base methods (ie: size)
if (name in target) {
return target[name];
}
// HOM methods
if (isHOM(name)) {
return makeHOM(proxy, name);
}
if (typeof target._array[name] == 'function') {
return function () {
var result = target._array[name].apply(target._array, arguments);
return Array.isArray(result) ? ForwardingList.apply(ForwardingList, result) : result;
}
}
return target._array[name];
},
set:function (target, name, value, receiver) {
target._array[name] = value;
}
};
proxy = new Proxy(target, handler);
return proxy;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment