-
-
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.