首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Object.observe()中的覆盖属性

Object.observe()中的覆盖属性
EN

Stack Overflow用户
提问于 2013-11-26 19:57:21
回答 1查看 593关注 0票数 1

我想使用Chrome的实验性Object.observe()来覆盖设置在对象上的所有函数:

→jsFiddle

代码语言:javascript
复制
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()被调用“。实际上可以在对象观察者中覆盖当前更改的值吗?

由于这只是一个实验(没有生产代码!),我欣赏任何一种解决方案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-29 19:45:09

好吧,你不能真正解决手头的问题。虽然您可以在观察者异步中再次覆盖更改的值,但是除非Object.deliverChangeRecords被显式调用,所以只有在obj.helloWorld()已经被调用之后才能执行它的定义。

我更新了您的小提琴以显示这一点:

代码语言:javascript
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20226720

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档