监控所有的JavaScript对象属性(魔术获得者和设置者)

如何在JavaScript中模拟PHP风格的__get()和__set()魔术getter / setters? 很多人都说这是不可能的。 我几乎可以肯定,这是可能的,因为像nowjs( http://nowjs.com )这样的项目做这样的事情。

我知道你可以利用get和set ,但是当你不确定属性的名字是什么时,这些不起作用。 例如, 如果您想要在创build新属性时执行事件处理程序,该怎么办?

我想要做的例子:

var obj = {}; notify(obj, function(key, value) { //key is now the name of the property being set. //value is the value of the property about to be set console.log("setting " + key + " to " + value); }); obj.foo = 2; //prints "setting foo to 2" obj.bar = {a: 2}; //prints "setting bar to [Object]" //Notice that notify() worked even though 'foo' and 'bar' weren't even defined yet! 

(这个问题类似于下面的问题:

  • 有没有办法监视对象的变化?
  • 所有属性的JavaScript getter

编辑:它看起来像这个function被称为“dynamic代理”,应出现在ECMAScript“和谐”标准(可能是ES6)。 你可以在这里阅读更多。 一个新的“代理”对象引入了几个方法(即创build()和createFunction())。

人可以这样做:

 //Constructing an object proxy (proto is optional) var proxy = Proxy.create(handler, proto); proxy.foo = 2; //Triggers 'set' function in the handler (read about it) 

底线在这里:它不适用于大多数浏览器,但有一个实现可用于Node.js: node-proxy 。

通过nowjs源代码来看,我相信他们通过不断监视now对象并在检测到客户端和服务器之间推送更改时这样做。 我承认我还没有完全熟悉他们的代码,但是。

在浏览器中,这将通过一些有趣的setInterval黑客来完成。

编辑 :是的,这的确是他们做的:客户端now.js 第368行 。 他们做了一些更多的技巧 ,一旦一个新的属性被发现,将来的访问被getter和setter捕获,但是这些修改只能在setTimeout每1000毫秒进行一次。

另一个证据表明,在当前的JavaScript中这是不可能的, ECMAScript Harmony的代理提案是明确地devise来实现这样的场景的,这意味着它们目前无法完成。 最近的Mozilla浏览器有一个原型代理实现 ,如果这也许就足够了。 显然V8正在努力添加支持 ,这可能是足够的,这取决于现在V8节点的版本。

编辑2 :哦,很酷,在服务器端显然nowjs确实使用代理! 这可能意味着它们在Node中足够成熟,可供您使用。 看看他们在Flotype/now/blob/master/lib/proxy.html 。 或者只是做var Proxy = require("nodejs-proxy")并希望他们遵循规范,以便您可以利用MDC和其他地方的文档。

在Firefox中,您可以使用Object.watch 。 如果你看看这个线程, 所有浏览器的Object.watch()? ,在所有的浏览器中都有使用它的例子。

哎呀,我只是意识到你想看所有的财产,而不是一个具体的财产…上面的解决scheme是观看一个特定的属性。

也许这个职位会帮助…? 但是,只有特定的属性和基于Gecko的浏览器…如果你需要支持其他浏览器,它的越野车,但你可以看看onpropertychange。 这是MSDN页面 。 希望有一点帮助…