ES5 的 Proxy 替代品
Proxy substitue for 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
属性 并在更改时重置所有 get
和 set
函数。这显然不是很有效,因为它会在添加或删除元素时更改每个元素的属性。
所以我认为 Object.defineProperty
不是答案。
我不想使用setInterval
的原因是因为间隔大会使包装不可靠,而间隔小则会对效率产生很大影响。
遗憾的是不,这就是代理如此重要的原因。目前没有其他方法可以在将 属性 添加到对象时触发代码,而不是代理。
如您所说,您可以使用 Object.defineProperty
或 var a = { get x() {...}, set x(value) {...} }
但不能检测新属性。
大多数框架依赖于dirty-check:在给定的时间比较对象。时间是主要区别所在。
AngularJS (Angular 1.x) 为你提供了异步操作的特殊功能,如 $timeout
和 $http
并且它自己的方式来听 DOM 将包装您的回调的事件和 运行 您的代码后的检查。
Angular (Angular 2 到 N) 使用 Zone.js 为您的代码创建一个 "Running context",任何异步回调都会被 Zone.js 拦截。它与 AngularJS 的解决方案基本相同,但可以自动运行。
React 做了类似的事情,但它不是跟踪变量,而是 运行 渲染器并比较生成的 DOM(虚拟 DOM)是否不同。
是否可以在不使用 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
属性 并在更改时重置所有 get
和 set
函数。这显然不是很有效,因为它会在添加或删除元素时更改每个元素的属性。
所以我认为 Object.defineProperty
不是答案。
我不想使用setInterval
的原因是因为间隔大会使包装不可靠,而间隔小则会对效率产生很大影响。
遗憾的是不,这就是代理如此重要的原因。目前没有其他方法可以在将 属性 添加到对象时触发代码,而不是代理。
如您所说,您可以使用 Object.defineProperty
或 var a = { get x() {...}, set x(value) {...} }
但不能检测新属性。
大多数框架依赖于dirty-check:在给定的时间比较对象。时间是主要区别所在。
AngularJS (Angular 1.x) 为你提供了异步操作的特殊功能,如 $timeout
和 $http
并且它自己的方式来听 DOM 将包装您的回调的事件和 运行 您的代码后的检查。
Angular (Angular 2 到 N) 使用 Zone.js 为您的代码创建一个 "Running context",任何异步回调都会被 Zone.js 拦截。它与 AngularJS 的解决方案基本相同,但可以自动运行。
React 做了类似的事情,但它不是跟踪变量,而是 运行 渲染器并比较生成的 DOM(虚拟 DOM)是否不同。