kirypto
kirypto

Reputation: 139

Design for a Watch tool in Javascript

I am looking at adding the ability to watch a variable to my code base, and I found this answer which does almost everything I need. The code that the answer provided is the following:

console = console || {}; // just in case
console.watch = function(oObj, sProp) {
    sPrivateProp = "$_"+sProp+"_$"; // to minimize the name clash risk
    oObj[sPrivateProp] = oObj[sProp];

    // overwrite with accessor
    Object.defineProperty(oObj, sProp, {
        get: function () {
            return oObj[sPrivateProp];
        },

        set: function (value) {
            //console.log("setting " + sProp + " to " + value); 
            debugger; // sets breakpoint
            oObj[sPrivateProp] = value;
        }
    });
}

To 'watch' a variable, you would use: console.watch(obj, "someProp");

However, I would like to know if it possible to add a 'unwatch' method that would undo the above? If so, how can that be done?

Upvotes: 0

Views: 105

Answers (2)

Ry-
Ry-

Reputation: 224905

First, some fixes to the original to make it simpler and also to make it work when the property doesn’t already exist on the object:

console = console || {};
console.watch = function (obj, prop) {
    var value_ = obj[prop];

    Object.defineProperty(obj, prop, {
        configurable: true,
        get: function () {
            return value_;
        },
        set: function (value) {
            debugger; // sets breakpoint
            value_ = value;
        }
    });
};

Then implementing unwatch is easy:

console.unwatch = function (obj, prop) {
    var value = obj[prop];
    delete obj[prop];
    obj[prop] = value;
};

Upvotes: 1

Maciej Sikora
Maciej Sikora

Reputation: 20132

console = console || {}; // just in case

//additional method use in watch or unwatch
console._defineProperty=function(oObj, sProp, watch){

    sPrivateProp = "$_"+sProp+"_$"; // to minimize the name clash risk
    oObj[sPrivateProp] = oObj[sProp];

    // overwrite property
    Object.defineProperty(oObj, sProp, {
      get: function () {
        return oObj[sPrivateProp];
      },
      set: function (value) {
        if (watch)//if true then watching if false then not watch
        console.log("setting " + sProp + " to " + value); 

        oObj[sPrivateProp] = value;
      }
    });
};

console.watch = function(oObj, sProp) {
  this._defineProperty(oObj,sProp,true);
};

console.unwatch = function(oObj, sProp) {
   this._defineProperty(oObj,sProp,false);
};

//USE CASE
var user={ name:"Tom"};
console.watch(user,"name");

user.name="Mike";//watching
user.name="Rafael";//watching

console.unwatch(user,"name");

user.name="John";//not wathing
user.name="Donatello";//not wathing

console.watch(user,"name");

user.name="Greg";//wathing
user.name="Ron";//wathing

Doing undo defineProperty is not possible so I am overriding property again but without additional not wanted behavior.

Upvotes: 1

Related Questions