JavaScript修改对象原型来监控变化
JavaScript Modify Object Prototype to Monitor Changes
我正在尝试修改Object
原型,以允许使用字符串比较监视整个对象(而不仅仅是Object.watch
的属性)的变化。下面是我到目前为止所做的,只要我在每次修改后调用myobj.change(...)
,它就可以工作。
我希望完成的是一种方法来"重新绑定".change()
对象,每次它被修改,所以我可以设置一个单一的变化处理程序,响应每当对象被操纵。
if (!Object.prototype.change) {
Object.defineProperty(Object.prototype, "change", {
value: function(handler) {
var curVal = JSON.stringify(this);
console.log('CUR:',curVal);
console.log('STATE:', this.__proto__.state);
if (curVal!==this.__proto__.state) {
this.__proto__.state = JSON.stringify(this);
handler.call(this);
}
}
});
}
var myobj = { foo: 'bar' };
myobj.change(function(){
console.log('Changed!');
});
myobj = { foo: 'qux' };
myobj.change(function(){
console.log('Changed!');
});
myobj = { foo: 'sit' };
myobj.change(function(){
console.log('Changed!');
});
小提琴在这里:http://jsfiddle.net/fluidbyte/GE9t3/
WatchAll对象
下面是一些快速而粗糙的代码,用于监视对象上定义的任何属性的更改。它要求初始化一个特定类型的新对象,WatchAll
。
代码var WatchAll = function (properties, change_handlers) {
var obj = Object.create(null);
var key;
var i;
for (key in properties) {
obj[key] = null;
Object.defineProperty(this, key, {
enumerable: true,
configurable: true,
get: function () {
return obj[key];
},
set: function (new_value) {
var old_value = obj[key];
obj[key] = new_value;
// notify the change handlers
for (i = 0; i < change_handlers.length; i++) {
change_handlers[i](key, old_value, new_value);
}
}
});
this[key] = properties[key];
}
};
function logUpdatedProperty (key, old_value, new_value) {
console.log(key + ' was changed from ' + old_value + ' to ' + new_value);
}
var myobj = new WatchAll({ foo: 'bar', testing: 123 }, [logUpdatedProperty]);
myobj.foo = 'qux'; // from bar to qux
myobj.foo = 'sit'; // from qux to sit
myobj.testing = 456; // from 123 to 456
myobj.foo = 'bar'; // from sit to bar
myobj.testing = 123; // from 456 to test
JavaScript版本/浏览器兼容性
我用NodeJS测试了代码,但它应该在任何浏览器中工作(当然除了IE8和IE7)。下面是Object.defineProperty的浏览器兼容性表。
用WatchAll包裹现有对象
要包装现有对象,只需枚举它们的属性,并使用正确的更改处理程序将它们的值复制到新的WatchAll对象:
function wrapWithWatchAll (obj, change_handlers) {
var propagateChangeBackToOriginalObject = function (key, old_value, new_value) {
obj[key] = new_value;
};
return new WatchAll(obj, [propagateChangeBackToOriginalObject].concat(change_handlers));
}
var existingobj = { name: 'omouse', skills: 'programming' };
var wrappedobj = wrapWithWatchAll(existingobj, [logUpdatedProperty]);
wrappedobj.name = 'rudolf'; // from omouse to rudolf
wrappedobj.skills = 'javascript'; // from programming to javascript
console.log('wrapped: ' + wrappedobj.name); // rudolf
console.log('existing: ' + existingobj.name); // rudolf
这里的问题是,您将不得不在任何地方使用已包装的对象,因此您必须将现有对象与已包装的对象交换。
相关文章:
- 单击页面上的链接后高度发生变化
- React redux初始化功能,无论状态变化如何
- 角度ng变化或ng点击选择can'不起作用
- 每个选择器的Jquery css颜色都在变化,但字体大小却没有变化
- JS幻灯片与CSS背景颜色变化
- 重新加载页面时Javascript变量发生变化
- 如何获得Bootstrap Datepicker的年和月,因为它在变化
- 如何用jquery替换字符串中可能变化的字符
- 检测数据的变化
- 如何检测和打印变化变量LESS
- 当文本不断变化时,如何避免在按钮内移动文本
- 当数据库中的某些内容发生变化时调用HTTP方法Meteor.js
- Greasemonkey脚本监控一个网站的变化
- JavaScript修改对象原型来监控变化
- ObservableArray子可观察对象变化监控
- Node.js监控文件的变化并解析它们
- 使用JavaScript监控帧的变化
- 使用jquery监控表单字段的变化
- jQuery监控表的变化
- 监控远程文件的变化,而不用用nodejs下载它