0

5 年間維持しているブラウザー アドオンを持っています。Firefox と Chrome のバージョン間で共通のコードをいくつか共有したいと思います。

Javascript Module Patternを使用することにしましたが、たとえば、ブラウザー固有の設定の読み込み、データの保存、およびその他のブラウザー依存のもので問題が発生しています。

私がやりたいのは、派生したブラウザー固有のサブモジュールで実装できる、オーバーライド可能な仮想メソッドを共有コードで参照することです。

以下は、参照した記事の Tight Augmentation メソッドを使用して、Firebug コンソールで試した、これまでの簡単な例です。

var core = (function(core)
{
    // PRIVATE METHODS
    var over = function(){ return "core"; };

    var foo = function() {
        console.log(over());
    };

    // PUBLIC METHODS
    core.over = over;
    core.foo = foo;

    return core;
}(core = core || {}));


var ff_specific = (function(base)
{
    var old_over = base.over;

    base.over = function() { return "ff_specific"; };

    return base;
}(core));

core.foo();
ff_specific.foo();

残念ながら、foo() への呼び出しはどちらも「コア」を出力しているように見えるので、根本的な誤解があると思います。

基本的に、私は電話できるようにしたいと思っています:

get_preference(key)
set_preference(key, value)
load_data(key)
save_data(key, value)

各ブラウザが独自の処理を行うようにします。これは可能ですか?それを行うより良い方法はありますか?

4

3 に答える 3

1

JavaScript の関数には「レキシカル スコープ」があります。これは、関数が実行時ではなく定義時に環境 - スコープを作成することを意味します。そのため、後で「over」機能を代用することはできません。

var over = function(){ return "core"; };

var foo = function() {
    console.log(over());
};
//this closure over "over" function cannot be changed later

さらに、「over」は「core」のプライベートメソッドであり、「ff_specific」は何らかの方法で「core」を拡張して変更する必要があると「言っています」(この場合、設計によってオーバーライドされることを意図していないプライベートメソッド)

于 2012-09-06T16:40:24.127 に答える
1

ff_specific コードで foo への呼び出しをオーバーライドすることはありません。これは、関数 core.over() (オーバーライドされる) ではなく、プライベート関数 over() (オーバーライドされない) を直接参照します。

ユースケースに基づいて解決する方法は、over() への呼び出しを core.over() への呼び出しに変更することです。

そうは言っても、物事の名前をあまりにも再利用することで、あなたは本当に自分自身を混乱させています. 多分それはサンプルコードのためだけです。また、基本関数にコアを渡す必要があるとは確信していません(子だけに)。

于 2012-09-06T16:38:41.103 に答える
0

ご協力いただきありがとうございます。クロージャーが定義された後、クロージャーを再割り当てできないことを忘れていました。私は解決策を見つけました。

問題の一部は、記事のサンプル コードにやみくもに従っただけでした。つまり、モジュールをビルドするための無名関数がすぐに呼び出されていました (Paul が言及した名前の再利用)。クロージャーを再割り当てできないということは、私が特別に公開したクロージャーであっても、独自のメソッドを持つオブジェクトを後で渡すことさえできなかったことを意味し、それらをチェックすることもできませんでした。

これが私がやったことであり、非常にうまく機能しているようです:

var ff_prefs = (function(ff_prefs)
{
    ff_prefs.foo = function() { return "ff_prefs browser specific"; };

    return ff_prefs;
}({}));


var chrome_prefs = (function(chrome_prefs)
{
    chrome_prefs.foo = function() { return "chrome_prefs browser specific"; };

    return chrome_prefs;
}({}));


var test_module = function(extern)
{
    var test_module = {};

    var talk = function() {
        if(extern.foo)
        {
            console.log(extern.foo());
        }
        else
        {
            console.log("No external function!");
        }
    };

    test_module.talk = talk;

    return test_module;
};


var test_module_ff = new test_module(ff_prefs);
var test_module_chrome = new test_module(chrome_prefs);
var test_module_none = new test_module({});

test_module_ff.talk();
test_module_chrome.talk();
test_module_none.talk();

以前は、それ自体が実行されていましたが、拡張機能が開始されたときに init() 関数を呼び出していましたが、これは引き続き実行できます。もはや匿名関数ではありません。

于 2012-09-06T16:58:54.377 に答える