我想使用Chrome的实验性Object.observe()来覆盖设置在对象上的所有函数:
→jsFiddle
var obj = {};
Object.observe(obj, function (changes) {
changes.forEach(function (data) {
if ((data.type == "new" || data.type == "updated") &&
typeof data.object[data.name] == "function" &&
typeof data.object[data.name].isWrapper == "undefined") {
data.object[data.name] = function () {
};
data.object[data.name].isWrapper = true;
}
});
});
obj.helloWorld = function () {
console.log("helloWorld() was called");
};
obj.helloWorld();不幸的是,控制台仍然显示"helloWorld()被调用“。实际上可以在对象观察者中覆盖当前更改的值吗?
由于这只是一个实验(没有生产代码!),我欣赏任何一种解决方案。
发布于 2013-11-29 19:45:09
好吧,你不能真正解决手头的问题。虽然您可以在观察者异步中再次覆盖更改的值,但是除非Object.deliverChangeRecords被显式调用,所以只有在obj.helloWorld()已经被调用之后才能执行它的定义。
我更新了您的小提琴以显示这一点:
var obj = {};
function obs(changes) {
changes.forEach(function (data) {
if ((data.type == "new" || data.type == "updated") &&
typeof data.object[data.name] == "function" &&
typeof data.object[data.name].isWrapper == "undefined") {
data.object[data.name] = function () {
console.log("intercepted", data.name);
};
data.object[data.name].isWrapper = true;
}
});
}
Object.observe(obj, obs);
obj.helloWorld = function () {
console.log("helloWorld() was called");
};
// Will call the original function, as changes are not yet delivered.
obj.helloWorld();
Object.deliverChangeRecords(obs);
// Will call the intercepted function, as the changes were explicitly delivered synchronously.
obj.helloWorld();
obj.helloWorld2 = function () {
console.log("helloWorld2() was called");
};
// Will call the intercepted function, as first the changes will be delivered (end of turn) and only then the timeout callback will be called.
setTimeout(function() { obj.helloWorld2(); }, 0);但是,不能完全确定setTimeout位是由规范提案隐式强制执行的,还是仅仅是一个实现细节。
由于如果没有显式执行Object.deliverChangeRecords的修改代码,就无法立即和同步地观察到任何更改,因此这个API实际上并不适合您试图实现的目标,至少在涉及当前的规范建议时是如此。
Object.observe的一个可行的替代方案可能是Proxy,它实际上就是要做这样的事情,而且IIRC在Chrome中也是可用的(打开了实验性的和谐特性)。这是Proxy。
https://stackoverflow.com/questions/20226720
复制相似问题