OK, so I'll start from the method you've suggested and it seems you like that approach.
Sorry, if this seems obvious but better to explain!
Basically watch
watches properties within your object (say datasource) and when a new value is assigned - fires the callback
function. So, watch takes two params - what to watch, and what to do (when the property you are watching changes).
The caveat with this approach is it's a a non-standard and was not implemented by other browsers. Although, we can get a polyfill (which declares it if it does not exist).
https://gist.github.com/eligrey/384583
Warning from Mozilla's own docs:
Deprecation warning: Do not use watch() and unwatch()! These two
methods were implemented only in Firefox prior to version 58, they're
deprecated and removed in Firefox 58+. In addition, using watchpoints
has a serious negative impact on performance, which is especially true
when used on global objects, such as window. You can usually use
setters and getters or proxies instead.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch
So, to implement using a polyfil of watch (thank Eli Grey for the Polyfill)
First, register the polyfill (put it somewhere which will run before anything else in JS, or put it in a polyfill.js file and import it first on your HTML page!)
/*
* object.watch polyfill
*
* 2012-04-03
*
* By Eli Grey, http://eligrey.com
* Public Domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
// object.watch
if (!Object.prototype.watch) {
Object.defineProperty(Object.prototype, "watch", {
enumerable: false
, configurable: true
, writable: false
, value: function (prop, handler) {
var
oldval = this[prop]
, newval = oldval
, getter = function () {
return newval;
}
, setter = function (val) {
oldval = newval;
return newval = handler.call(this, prop, oldval, val);
}
;
if (delete this[prop]) { // can't watch constants
Object.defineProperty(this, prop, {
get: getter
, set: setter
, enumerable: true
, configurable: true
});
}
}
});
}
// object.unwatch
if (!Object.prototype.unwatch) {
Object.defineProperty(Object.prototype, "unwatch", {
enumerable: false
, configurable: true
, writable: false
, value: function (prop) {
var val = this[prop];
delete this[prop]; // remove accessors
this[prop] = val;
}
});
}
Then, to use (using your example);
var test;
**function myObject(){
this.dataSource = null;
this.changeEvent = function (id, oldval, newval) {
console.log(id + ' changed from ' + oldval + ' to ' + newval);
return newval;
}
this.watch('datasource', this.changeEvent);
}**
test = new myObject();
test.dataSource = 'dataSource'; //trigger changeEvent() inside myObject
However, I would look into Event Listeners and trigger events when objects change - but that solution should work for you, especially with watch
Listening for variable changes in JavaScript