nic*_*oum 14 javascript object ecmascript-5 es5-compatiblity
是否可以不使用Proxy和来监听属性更改setInterval?
对于常见对象,您可以使用下面的函数,但该函数适用于所有现有属性,但不适用于包装后可能添加的任何属性。
function wrap(obj) {
var target = {};
Object.keys(obj).forEach(function(key) {
target[key] = obj[key];
Object.defineProperty(obj, key, {
get: function() {
console.log("Get");
return target[key];
},
set: function(newValue) {
console.log("Set");
target[key] = newValue;
}
});
});
}
var obj = {
a: 2,
b: 3
};
wrap(obj);
obj.a; // Get
obj.a = 2; // Set
obj.b; // Get
obj.b = 2; // Set
obj.c = 2; // Nothing
obj.c; // NothingRun Code Online (Sandbox Code Playgroud)
如果对象是数组,则还可以侦听该length属性,get并set在更改后重置所有和函数。这显然不是很有效,因为每当添加或删除元素时,它都会更改每个元素的属性。
因此,我认为这Object.defineProperty不是答案。
我不想使用的原因setInterval是,间隔时间过长会导致包装不可靠,而间隔时间过短则会对效率产生很大影响。
遗憾的是没有,这就是代理如此重要的原因。目前,除了 Proxy 之外,没有其他方法可以在将属性添加到对象时触发代码。
\n\n正如您所说,您可以使用Object.defineProperty或var a = { get x() {...}, set x(value)\xc2\xa0{...}\xc2\xa0}但不能检测新属性。
大多数框架依赖于脏检查:在给定的时间上比较对象。时间是主要区别所在。
\n\nAngularJS (Angular 1.x) 为您提供了用于异步操作的特殊函数,例如$timeout和$http,并且它有自己的方式来侦听 DOM 事件,这些事件将包装您的回调并在代码之后运行检查。
Angular(Angular 2 到 N)使用Zone.js为您的代码创建“运行上下文”,任何异步回调都会被 Zone.js 拦截。它基本上与 AngularJS 的解决方案相同,但可以自动工作。
\n\nReact 做了类似的事情,但它不是跟踪变量,而是运行渲染器并比较生成的 DOM(虚拟 DOM)是否不同。
\n