我想使用Chrome的实验Object.observe()来覆盖对象上设置的所有函数:
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()被称为”。实际上是否可以覆盖对象观察者中当前更改的值?
由于这只是一个实验(没有生产代码!),我感谢任何解决方案。
答案 0 :(得分:1)
嗯,你无法真正解决手头的问题。
虽然您可以在观察者the observer is only executed asynchronously中再次覆盖更改的值,除非明确调用Object.deliverChangeRecords
,因此只有在obj.helloWorld()
已经被定义的同一回合中调用后才会执行。< / p>
我更新了您的fiddle以显示:
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中使用(启用实验和声功能)。
这是a fiddle using Proxy
。