-
-
Save jaz303/9688740 to your computer and use it in GitHub Desktop.
| // signal is a function that creates an object to which listeners | |
| // can be attached. think of it like an EventEmitter with a single | |
| // event. | |
| var signal = require('signalkit'); | |
| function property(value) { | |
| var sig = signal(); | |
| var prop = function(newValue) { | |
| if (arguments.length === 0) { | |
| return value; | |
| } else { | |
| var oldValue = value; | |
| value = newValue; | |
| sig.emit(prop, value, oldValue); | |
| return true; | |
| } | |
| } | |
| prop.onChange = sig; | |
| return prop; | |
| } | |
| function property(value) { | |
| var sig = signal(); | |
| var prop = { | |
| get: function() { | |
| return value; | |
| }, | |
| set: function(newValue) { | |
| oldValue = value; | |
| value = newValue; | |
| sig.emit(prop, value, oldValue); | |
| return true; | |
| }, | |
| onChange: sig | |
| } | |
| } |
latentflip
commented
Mar 21, 2014
As standalone object, I think the first way is two confusing. It might make more sense as part of another object:
var phil = {
age: property(10);
}
phil.age() //=> 10
phil.age(20)but if you were going to do that, why not just use Object.defineProperty.
I agree it looks better that way.
I'm not using Object.defineProperty because I'm building a UI that edits a dozen or so properties at once, and those properties do not all belong to the same object. There's also a bunch of other metadata like title and the type of widget used to edit each property. Also, the list of editable properties is not static and I need to be able watch for properties being added/deleted.
Another option is to do away with fine-grained property objects and just have the user provide an object that satisfies a simple API like this:
delegate.getEditablePropertyNames() // => ['foo', 'bar', 'baz']
delegate.get('foo') // => 10
delegate.set('foo', 20) // => true
delegate.get('foo') // => 20
Or I guess I could extend that to generating an on-demand proxy-object with Object.defineProperty + getters/setters, but I'd still need an auxiliary API for monitoring changes.