X

Sundararajan's Weblog

  • Java
    November 3, 2005

Field assignment watch in JavaScript

Guest Author
JavaScript supports watch method for every script Object. This method adds a watchpoint to a property of the object. Whenever a value is assigned to the mentioned property, it calls up a handler function allowing you to watch the new value assigned. If required, you can even alter the value assigned.
But, this is supported only in SpiderMonkey, but not in Rhino. As you may know already, Mustang includes Rhino. So, what do we do? Well, we can use JSAdapter to implement a similar feature.

// creates a wrapper for a given object. The wrapper
// objects passes field access/assignment to the wrapped
// object except for the watched property. For the watched
// property, the wrapper calls a callback function.
function WatchWrapper(obj, prop, callback) {
return new JSAdapter() {
__has__: function(name) {
return (name in obj);
},
__get__: function(name) {
return obj[name];
},
// if property assigned is the watched property
// then, call the callback function. Otherwise
// just assign the field value.
__put__: function(name, value) {
if (name == prop) {
callback(obj, name, value);
} else {
obj[name] = value;
}
}
};
}

Let us say you want watch assignment to salary field in Employee objects:

function Employee(nm, sal) {
this.name = nm;
this.salary = sal;
}

We can change the above code as below:

function salaryWatcher(emp, name, newSal) {
if (emp.name == 'sundararajan') {
emp.salary = newSal \* 100; // make it 100 times :-)
} else {
emp.salary = newSal;
}
return emp.salary;
}
function Employee(nm, sal) {
return WatchWrapper(
{ name: nm, salary: sal },
"salary",
salaryWatcher);
}


Note that the call sites that use Employee constructor need not change at all (whether or not field modification is watched). We can remove the watch by simply reverting back to the original code of the Employee function.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.