大多数动态语言都有一些拦截方法调用的方法。例如,所有 ruby 对象都有一个方法“method_missing”,只要对未定义的对象调用方法,就会调用该方法。您可以使用此功能设置代理对象以跟踪 lastModified 值。另一种动态语言,Actionscript 3.0 有一个代理API 中的类。同样,您可以使用此代理类来拦截函数调用。不幸的是,使用这样的代理意味着您必须修改定义方法的方式。在 ruby 的情况下,method_missing 显然只在方法不存在时才被调用。这意味着您必须在一个对象上定义您的方法,然后由代理类包装。看看我在 AS3 中整理的示例。要跟踪的属性必须通过 trackSet 方法定义,我们不能直接在 MyObject 类上定义该方法。trackSet 将属性的名称存储在对象中以及回调函数中。当在代理类上调用 setProperty 时,会根据 setters 对象检查属性的名称,如果存在 lastModified 则更新该属性并调用该属性回调。
package {
import flash.utils.Proxy;
import flash.utils.flash_proxy;
public dynamic class Tracker extends Proxy {
private var setters : Object;
public function Tracker() {
setters = { };
}
public function getLastModified(name : String) : Number {
return setters[name] ? setters[name].lastModified : 0;
}
protected function trackSet(name : String, fn : Function) : void {
setters[name] = {
lastModified: 0,
setter: fn
};
}
override flash_proxy function setProperty(name : *, value : *) : void {
if(!setters[name]) return;
setters[name].lastModified = new Date().time;
setters[name].setter(value);
}
}
}
-
package {
public dynamic class MyObject extends Tracker {
public function MyObject() {
trackSet('member', setMember);
}
private function setMember(val : String) : void {
trace('set member =', val);
}
}
}
-
var obj : MyObject = new MyObject();
obj.member = 'monkey';
trace('member getlast modified at', obj.getLastModified('member'));