1

Google の Closure Compiler を高度なモードで使用していますが、奇妙な問題が発生しています。コンパイルされたバージョンの実行から返されたログ ステートメントを含む、コンパイルされていないコードを次に示します。

goog.provide('frame.store');

goog.require('frame.storeBack.LocalStore');
goog.require('frame.storeBack.Mem');

frame.store = (function() {
    /** prioritised list of backends **/
    var backends = [
        frame.storeBack.LocalStore,
        frame.storeBack.Mem
    ];

    frame.log(backends); 
    // [function rc(){}, function tc(){this.q={}}]

    frame.log(frame.storeBack.LocalStore === backends[0]); 
    // true

    frame.log(frame.storeBack.LocalStore.isAvailable === backends[0].isAvailable); 
    // false

    frame.log(frame.storeBack.LocalStore.isAvailable);
    // function sc(){try{return"localStorage"in window&&window.localStorage!==k}catch(a){return l}}

    frame.log(backends[0].isAvailable);
    // undefined

    for (var i=0, len=backends.length; i<len; i++)
        if (backends[i].isAvailable())
            return new backends[i]();
    // Uncaught TypeError: Object function rc(){} has no method 'Ga'

    throw('no suitable storage backend');
})();

何らかの理由で、静的メソッド isAvailable は、バックエンド配列を介して LocalStore にアクセスするときに存在せず、グローバル名前空間を介してアクセスするときに存在します。

誰でも理由がわかりますか?

編集:参考までに、ここにメソッド宣言があります:

frame.storeBack.LocalStore.isAvailable = function() {
    try {
        return 'localStorage' in window && window['localStorage'] !== null;
    }catch (e) {
        return false;
    }
};
4

2 に答える 2

2

オン--debug trueにして、出力とframe.storeBack.LocalStore.isAvailable名前が変更されたものを確認します。

変数名マップをダンプして、frame.storeBack.LocalStore.isAvailableフラット化されているかどうかを確認します。

たとえば、Closure Compilerframe.storeBack.LocalStore.isAvailable最初ににフラット化してからframe$storeBack$LocalStore$isAvailable、全体をグローバル関数 "a" などに名前変更します。これは名前空間のフラット化と呼ばれます。デバッグ出力をチェックして、関数宣言の名前が次のように変更されているかどうかを確認します。

$frame$storeBack$LocalStore$isAvailable$$ = function() {

そのような場合、frame.storeBack.LocalStore.isAvailable()直接呼び出すとフラット化されたグローバル バージョンが呼び出されますが、問題はありません。ただし、 (別のオブジェクト)isAvailable()に存在することを期待することはできません。frame.storeBack.LocalStoreコンパイルされた出力では、frame.storeBack.LocalStore.isAvailableframe.storeBack.LocalStoreが分離されるようになりました。これは、発生した場合のコンパイラの名前空間の平坦化の動作です。

プロパティをコンストラクター関数自体に入れるのに問題があることを求めています-コンパイラーは、予期しないクラスに対して多くの最適化を行います。

デバッグ出力と変数名マップをチェックして確認します。マップ ファイル内の実際の名前を表示するには、クロージャ ラッパー関数を削除する必要がある場合があります。

于 2011-03-26T02:35:54.713 に答える
1

バックエンドが正確に何であるかわかりません...しかし、それらをインスタンス化するべきではありませんか?

var backends = { localStore : new frame.storeBack.LocalStore(),
                 mem:         new frame.storeBack.Mem() };
于 2011-03-25T15:49:39.223 に答える