Skip to content

Instantly share code, notes, and snippets.

@jaz303
Created July 18, 2013 14:31
Show Gist options
  • Save jaz303/6029803 to your computer and use it in GitHub Desktop.
Save jaz303/6029803 to your computer and use it in GitHub Desktop.
private data patterns in JS
// I saw this programming style somewhere a while back and liked it.
function PubSub(subject) {
var observers = [];
subject.notify = function() {
for (var i = 0; i < observers.length; ++i) {
try {
observers[i].apply(null, arguments);
} catch (e) {
setTimeout(function() { throw e; }, 0);
}
}
}
subject.observe = function(obs) {
observers.push(obs);
return function removeObserver() {
observers.splice(observers.indexOf(obs), 1);
};
}
}
function makeObject() {
var obj = {};
var notifyPending = null;
function access(k, v) {
if (arguments.length === 1) {
return obj[k];
} else {
obj[k] = v;
if (!notifyPending) {
notifyPending = setTimeout(function() {
notifyPending = null;
access.notify();
}, 0);
}
}
}
PubSub(access);
return access;
}
var obj = makeObject();
obj('foo', 'bar');
obj('foo'); // => 'bar'
obj.observe(function() {
});
obj('baz', 'bleem');
function makeProperty(value, getter, setter) {
function rawGet() { return value; }
function rawSet(v) { value = v; }
// could also have getter/setter as function factories
if (!getter) getter = function(raw) { return raw(); };
if (!setter) setter = function(raw, v) { return raw(v); };
function property(v) {
if (arguments.length === 0) {
return getter(function() { return value; });
} else {
return setter(function(v) { value = v; }, v);
}
}
return property;
}
function makeAttribute(value, getter, setter) {
var pubsub = {};
PubSub(pubsub);
var notify = pubsub.notify;
var property = makeProperty(value, getter, function(raw, v) {
// ... mojo
notify();
});
property.observe = pubsub.observe;
return property;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment