监控所有JavaScript对象属性(魔术getter和setter)

时间:2011-08-08 16:50:30

标签: javascript node.js setter getter

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

我知道您可以使用getset,但是当您不确定属性名称是什么时,这些不起作用。例如,如果您希望在创建新属性时执行事件处理程序,该怎么办?

我想做的例子:

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!

(问题类似于以下问题:

编辑:看起来这个功能被称为“动态代理”,应该出现在ECMAScript“Harmony”标准中(可能是ES6)。您可以阅读更多here。一个新的“代理”对象引入了几个方法(即:Create()和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

3 个答案:

答案 0 :(得分:13)

通过nowjs源代码,我相信他们通过持续监视now对象并在检测到客户端和服务器之间推送更改来实现此目的。但我承认我还没有完全理解他们的代码。

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

编辑:是的,这确实是他们所做的:line 368客户now.js。它们执行some more tricks,以便一旦检测到新属性,将来访问它将被getter和setter捕获,但这些修改仅在setTimeout中每1000毫秒进行一次。

另一个证据表明,在当前的JavaScript中这是不可能的,the proxies proposal for ECMAScript Harmony是明确设计用于启用此类场景,这意味着它们目前无法完成。最近的Mozilla浏览器有a prototype proxies implementation,如果这还不够。显然V8 is working to add support,这可能已经足够,这取决于最近使用的V8节点的版本。

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

答案 1 :(得分:2)

在Firefox中,您可以使用Object.watch。如果你看一下这个帖子Object.watch() for all browsers?,就会有一个在所有浏览器中使用它的例子。

哎呀,我刚刚意识到你想要观看所有的房产,而不是特定的房产...上面的解决方案是观看特定的房产。

答案 2 :(得分:0)

也许this post会有帮助......?但是,仅适用于特定属性和基于Gecko的浏览器......如果您需要支持其他浏览器,它的错误,但您可以查看onpropertychange。这是MSDN Page。希望有所帮助...

相关问题