如何在 JavaScript 中模拟 PHP 风格的 __get() 和 __set() 魔术 getter/setter?很多人说,目前这是不可能的。我几乎可以肯定这是可能的,因为像 nowjs 这样的项目(http://nowjs.com http://nowjs.com)做这样的事情。
我知道你可以利用get https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/get and set https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/set,但是当您不确定属性名称是什么时,这些不起作用。例如,如果您希望在创建新属性时执行事件处理程序该怎么办?
我想做的事情的例子:
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!
(这个问题类似于以下问题:
- 有没有办法监视对象的变化? https://stackoverflow.com/questions/6216553/is-there-a-way-to-monitor-changes-to-an-object
- 所有属性的 JavaScript getter https://stackoverflow.com/questions/994143/JavaScript-getter-for-all-properties
)
EDIT:看起来这个功能被称为“动态代理”,应该出现在 ECMAScript“Harmony”标准(可能是 ES6)中。您可以阅读更多内容here http://wiki.ecmascript.org/doku.php?id=harmony:proxies。引入了一个新的“代理”对象,并带有几个方法(即 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 有一个实现:节点代理 https://github.com/samshull/node-proxy.
浏览 nowjs 源代码,我相信他们是通过持续监控来做到这一点的now
对象并在检测到变化时在客户端和服务器之间推送变化。不过,我承认我还没有完全理解他们的代码。
在浏览器中,这会很有趣setInterval
hacks.
EDIT:是的,这确实是他们所做的:line 368 https://github.com/Flotype/now/blob/be675edea9d968c2cc6aebd91e55eb0e96abd39d/lib/client/now.js#L368客户的now.js
。他们是这样还有一些技巧 https://github.com/Flotype/now/blob/be675edea9d968c2cc6aebd91e55eb0e96abd39d/lib/client/now.js#L164这样,一旦检测到新属性,未来对其的访问就会被 getter 和 setter 捕获,但这些修改仅在 a 中每 1000 毫秒进行一次setTimeout
.
另一个证明这在当前 JavaScript 中不可能的证据是ECMAScript Harmony 的代理提案 http://wiki.ecmascript.org/doku.php?id=harmony:proxies明确设计为实现此类场景,这强烈暗示它们目前无法完成。最近的 Mozilla 浏览器有原型代理实现 https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Proxy,如果这样就足够了。显然V8 正在努力添加支持 http://code.google.com/p/v8/issues/detail?id=1543,这可能就足够了,具体取决于目前使用的 V8 Node 版本。
EDIT2: 哦,酷,在server显然 nowjs 确实使用代理!这可能意味着它们在 Node 中已经足够成熟,可供您使用。看看他们在做什么https://github.com/Flotype/now/blob/master/lib/proxy.js https://github.com/Flotype/now/blob/master/lib/proxy.js。或者只是做var Proxy = require("nodejs-proxy")
并希望他们遵循规范,以便您可以利用 MDC 和其他地方的文档。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)