监视所有JavaScript对象属性(魔术getter和setter)
Monitor All JavaScript Object Properties (magic getters and setters)
如何在JavaScript中模拟php风格的__get()和__set()魔法getter/setter ?很多人说这在目前是不可能的。我几乎可以肯定这是可能的,因为像nowjs (http://nowjs.com)这样的项目做了这样的事情。
我知道你可以使用get和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!
这个问题类似于下面的问题:
- 是否有一种方法来监控对象的变化?
- 所有属性的JavaScript getter
)
EDIT:看起来这个功能被称为"动态代理",应该出现在ECMAScript"Harmony"标准中(可能是ES6)。你可以在这里阅读更多。一个新的"代理"对象引入了两个方法(即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.
查看nowjs源代码,我相信他们通过持续监视now
对象并在检测到它们时在客户端和服务器之间推送更改来实现这一点。然而,我承认我还没有完全理解他们的代码。
在浏览器中,这可以通过一些有趣的setInterval
hack来完成。
EDIT:是的,这确实是他们所做的:客户端now.js
的第368行。他们做了一些更多的技巧,以便一旦检测到新属性,getter和setter将捕获对它的未来访问,但是这些修改仅在setTimeout
中每1000毫秒进行一次。
在当前的JavaScript中,这是不可能的另一个证据是ECMAScript Harmony的代理建议被明确地设计为支持这种场景,这强烈暗示它们目前无法完成。最近的Mozilla浏览器有一个原型代理实现,如果这就足够了。显然V8正在努力增加支持,这可能足够了,这取决于目前使用的是哪个版本的V8 Node。
EDIT2:哦,酷,在服务器端显然现在js使用代理!这可能意味着它们在Node中已经足够成熟,可以供您使用。看看他们在https://github.com/Flotype/now/blob/master/lib/proxy.js做什么。或者只做var Proxy = require("nodejs-proxy")
,并希望它们遵循规范,这样您就可以利用MDC和其他地方的文档。
在Firefox中,可以使用Object.watch。如果你看一下这个线程,Object.watch()适用于所有浏览器?,这里有一个在所有浏览器中使用它的例子。
哎呀,我刚刚意识到你想看所有的属性,而不是一个特定的属性…上面的解决方案是监视一个特定的属性。
也许这篇文章会有所帮助…?然而,这只是针对特定属性和基于Gecko的浏览器…如果你需要其他浏览器的支持,它是有bug的,但是你可以看看onpropertychange。这是MSDN页面。
- 查看JS对象的所有键,甚至是getter定义的键
- 用于'魔术串'属性
- "实例范围”;TypeScript类的getter/setter
- 重写不带defineProperty的对象getter
- 无填充的滚动魔术持续时间
- 如何防止在javascript中执行继承属性的getter-setter方法
- JavaScript 对象中的私有成员,带有 getter 和 setter
- localStorage-对象的getter-, setter-方法的目的是什么?
- 传递参数时如何避免模块模式中的 getter/setter 函数
- 为 getter 提供默认值,而不会在 Angular 2 模型类中导致堆栈溢出
- 引用属性而不是 getter 和 setter
- JSDoc:如何避免属性/getter的文档重复
- 使用特权Getter/Setter函数的JavaScript原型函数
- 调用Typescript setter don't返回函数,尽管关联的getter可以工作
- 使用框架/语言中的getter/setter,或者定义自己的显式getter/setters
- 使用getter和setter实现函数链接的方法
- 什么类型的对象/属性是原型getter和setter
- getter和setter只适用于ES5中的基元值吗
- 未捕获的类型错误:无法设置#的属性playerNo,该属性在第4行只有一个getter
- 监视所有JavaScript对象属性(魔术getter和setter)