1

オブジェクトに設定されているすべての関数を上書きするために、 Chrome の実験的なObject.observe()を使用したいと考えています。

→ jsフィドル

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() が呼び出されました」と表示されます。オブジェクトオブザーバーで現在変更されている値を実際に上書きすることは可能ですか?

これは実験にすぎないので (本番コードはありません!)、どんな種類の解決策も歓迎します。

4

1 に答える 1

1

さて、あなたは目の前の問題を本当に解決することはできません。オブザーバーで変更された値を再度上書きすることはできますが、オブザーバーは明示的に呼び出されない限り非同期でのみ実行されるため、定義された同じターンで既に呼び出された後にのみ実行されます。Object.deliverChangeRecordsobj.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これは、実際にはこのようなことを行うことを意図しており、 IIRCProxyは Chrome でも利用できます (実験的なハーモニー機能がオンになっています)。を使用したフィドルをProxy次に示します。

于 2013-11-29T19:45:09.387 に答える