ES5的代理替代

尼克·祖姆

是否可以不使用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; // Nothing

如果对象是数组,则还可以侦听该length属性,getset在更改后重置所有函数。这显然不是很有效,因为每当添加或删除元素时,它都会更改每个元素的属性。

因此,我认为这Object.defineProperty不是答案。

我不想使用的原因setInterval是,间隔时间过长会使包装不可靠,而间隔时间过短会对效率产生很大影响。

马蒂亚斯·奎萨达(A.MatíasQuezada)

遗憾的是,这就是代理如此重要的原因。目前,除了代理之外,没有其他方法可以将代码添加到对象时触发代码。

如您所说,您可以使用Object.definePropertyvar a = { get x() {...}, set x(value) {...} }不能检测新属性。


大多数框架都依赖于脏检查:在给定的时间比较对象。时机主要是差异所在。

AngularJS(Angular 1.x)为您提供了诸如$timeout$http异步操作的特殊功能,这是侦听DOM事件的独特方式,该事件将包装您的回调并在代码执行之后进行检查。

Angular(2到N之间的角度)使用Zone.js为您的代码创建“运行上下文”,Zone.js会拦截任何异步回调。它基本上与AngularJS相同,但可以自动运行。

React做了类似的事情,但是它运行渲染器并比较生成的DOM(虚拟DOM)是否不同,而不是跟踪变量。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章