本文介绍在 JavaScript 中监控变量变化的两种方法。首先通过仿照 C# 属性机制,将赋值操作封装在 setter 方法中并触发回调来实现监听。其次介绍利用非标准的 Object.watch 和 unwatch 方法直接监控对象属性变更,并指出该方法在 IE 浏览器中的兼容性问题。
JavaScript 变量监听概述
本文通过具体实例介绍在 JavaScript 中监控变量变化的实现方式,供读者参考。
在 C# 等语言中,监控属性或文件变更较为便捷,主要得益于委托(事件)机制以及 FileSystemWatcher 等内置工具的支持。
基于 Setter 方法的自定义监听方案
那么在 JavaScript 中,如何实现对变量变更的监控?首先,我们可以参考 C# 属性的设计思路,构建如下示例代码:
function Class1()
{
var oldValue='';
var name='xu';
var id='1';
this.setName=function(n)
{
oldValue=name;
name=n;
this.propertyChange('name',oldValue,n);
}
this.setID=function(n)
{
oldValue=id;
id=n;
this.propertyChange('id',oldValue,n);
}
this.display=function()
{
alert(name+'\'s id is :'+id);
}
}
Class1.prototype={
propertyChange:function(propertyName,oldValue,newValue)
{
alert(propertyName+'\'s value changed from '+oldValue+' to '+newValue);
}
};
var c=new Class1();
c.setName('xu22');
c.setID('5');
c.display();
该方案将对象内部变量(即私有变量)的赋值逻辑提取到特定的方法中,并在该方法执行时触发相应的值变更回调函数。
使用 Object.watch 监控属性变更
理论上,这种封装方式即可实现变量变更的监控。然而,Mozilla 官方网站提供了一组名为 Object.watch 和 unwatch 的方法,专门用于监控变量值的变更。
遗憾的是,Object.watch 方法在 Internet Explorer 等浏览器中无法正常运行。为此,笔者查阅了相关技术社区,
http://stackoverflow.com/questions/1269633/javascript-watch-for-object-properties-changes
中找到了相关的解决方案:
if (!Object.prototype.watch)
{
Object.prototype.watch = 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])
{
if (Object.defineProperty) // ECMAScript 5
{
Object.defineProperty(this, prop, {get: getter,set: setter});
}
else if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__)
{
Object.prototype.__defineGetter__.call(this, prop, getter);
Object.prototype.__defineSetter__.call(this, prop, setter);
}
}
};
}
if (!Object.prototype.unwatch)
{
Object.prototype.unwatch = function (prop)
{
var val = this[prop];
delete this[prop];
this[prop] = val;
};
}
通过 __defineSetter__ 方法来监听赋值操作。
这是一个实用的方案,值得收藏备用。
希望本文所述的 JavaScript 程序设计技巧能对读者有所帮助。