可观察对象
创建一个函数 makeObservable(target)
,通过返回一个代理来“使对象可观察”。
以下是它的工作原理
function makeObservable(target) {
/* your code */
}
let user = {};
user = makeObservable(user);
user.observe((key, value) => {
alert(`SET ${key}=${value}`);
});
user.name = "John"; // alerts: SET name=John
换句话说,由 makeObservable
返回的对象与原始对象相同,但还具有 observe(handler)
方法,该方法将 handler
函数设置为在任何属性更改时调用。
每当属性更改时,都会调用 handler(key, value)
,其中包含属性的名称和值。
附注:在本任务中,请只关注写入属性。其他操作可以以类似的方式实现。
该解决方案包含两个部分。
- 每当调用
.observe(handler)
时,我们需要将处理程序存储在某个地方,以便以后能够调用它。我们可以使用我们的符号作为属性键,将处理程序直接存储在对象中。 - 我们需要一个带有
set
陷阱的代理,以便在发生任何更改时调用处理程序。
let handlers = Symbol('handlers');
function makeObservable(target) {
// 1. Initialize handlers store
target[handlers] = [];
// Store the handler function in array for future calls
target.observe = function(handler) {
this[handlers].push(handler);
};
// 2. Create a proxy to handle changes
return new Proxy(target, {
set(target, property, value, receiver) {
let success = Reflect.set(...arguments); // forward the operation to object
if (success) { // if there were no error while setting the property
// call all handlers
target[handlers].forEach(handler => handler(property, value));
}
return success;
}
});
}
let user = {};
user = makeObservable(user);
user.observe((key, value) => {
alert(`SET ${key}=${value}`);
});
user.name = "John";