【问题标题】:Monitor All JavaScript Object Properties (magic getters and setters)监控所有 JavaScript 对象属性(魔术 getter 和 setter)
【发布时间】:2011-10-22 13:41:16
【问题描述】:

如何在 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

【问题讨论】:

  • 这个称为代理的功能是 ECMAScript 6 而不是 5 的一部分。
  • 好收获。修改了我的帖子。谢谢!

标签: javascript node.js setter getter


【解决方案1】:

查看nowjs源代码,我相信他们通过持续监控now对象并在检测到它们时在客户端和服务器之间推送更改来做到这一点。不过,我承认我还没有完全理解他们的代码。

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

编辑:是的,这确实是他们所做的:客户now.jsline 368。他们这样做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 Node 版本。

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

【讨论】:

  • 好吧...我可以理解客户端的黑客攻击,尤其是浏览器兼容性问题的 b/c。服务器端呢?比如,在 Node.JS 上?你认为有可能在那里做点什么吗?
  • 我实际上只是在你评论的时候用我的发现编辑了我的帖子:)
【解决方案2】:

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

糟糕,我刚刚意识到您想查看所有属性,而不是特定属性...上面的解决方案是查看特定属性。

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 感谢您的帮助。 onpropertychange 看起来只适用于 DOM 对象。这需要适用于普通的原始 JS 对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-24
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    相关资源
    最近更新 更多