2016-05-20 6 views
0

現在、私のGWT(バージョン2.5.1)アプリケーションでFirefox 46以降に発生するいくつかの奇妙なエラーをデバッグしています。GWTによって生成されたjavascriptコードには、このパターンの複数のインスタンスが含まれています:javacriptの関数宣言の再割り当て

function nullMethod() { 
} 

var v; 
function f() { 
    f = nullMethod; 
    v = { name : 'Joe' }; 
    console.log("called"); 
} 

// this is called from multiple places 
console.log((f(), v).name); 
console.log((f(), v).name); 
console.log((f(), v).name); 

これは何とかシングルトンパターンを実装しているようです。しかし、何らかの理由でこれが初期の宣言されたメソッドが再び呼び出されることを妨げるものではありません。 'called'という文字列がコンソールに複数回出力されます。

しかし、私は少しテストでこれを再現しようとすると、すべて期待どおりに動作します。上記からの観測は、生成されたコード(> 5MB)にコンソール出力を追加することによって行われました。

今、本当に奇妙なものです。関数の最初の文として "console.log(f.toString())"を追加すると、最初の呼び出しで初期関数が出力されます。それ以降のすべての呼び出しはnullMethodを出力します。

誰かが何が原因なのか説明できますか? IE11は正常に動作します。 ChromeはFirefox 46と同じ問題を抱えています。この動作が導入されて以来、私は古いChromeバージョンを確認することができませんでした。このように宣言された関数を上書きすることは有効ですか?

jsbin.comは、機能の再割り当てライン上の警告が得られる:この場合

Line 6: 'f' is a function. 

答えて

1

方法fをJavaの静的初期化子です。これを複数回実行すると、エミュレートされたJavaに問題が発生します。これは、クラスが最初に参照またはロードされるときに一度だけ実行できることを期待しています(GWTがクラスローダーをエミュレートしないため、クラスローダーの問題は無視されます)。 GWTの

しかし、十分に古いコピーはtry/catchブロック(IIRCこれはIE6の問題に関連していた)で、コードのブロックを包む、そして時に、JSのスコープルールは、このコードの動作をした彼らの周りのいくつかのあいまいさを持っていましたすべてのブラウザがこれをサポートして以来、一貫しています。これは、「粗雑なモード自己定義関数」として知られていました。

ES2015の一部として、tryブロックが外側の "関数ホスト"のスコープと異なるスコープを持つことが決定されました(つまり、function foo() {...}として宣言すると、上位レベルのスコープに存在します)。これに関する議論のトンをhttps://github.com/tc39/ecma262/issues/162で見てください。

この変更は、以前は正常だったプログラムの一部が正常に機能しなくなったことを意味します。これには、Google Inboxなどが含まれていました。

新しいバージョンのGWTに更新するか、古いGWTのトップレベルJSの各ブロックをもうラップしないカスタムLinkerを使用してこれを解決する必要があります。この行動を必要とする古代のブラウザをサポートしなければならないのであれば(十分なコード考古学を使って、GWTがなぜそれをやったのかを知ることはできますが、まだこれをしていません)、古くから流行しているブラウザーでも機能する妥協案です

+0

ありがとうございます!今私は、私が取り組んでいるいくつかのプロジェクトを検証しなければならないことを知っています。 –

+0

GWT 2.5.1が影響を受けることは知っています。私はネット上でこの問題に関するさらなる情報を見つけられませんでした。シンプルなデモアプリケーションを使用して、さまざまなGWTバージョンでこの問題を再現しました。しかし、コンパイラが常に欠陥のあるコードを発行するとは限りません。アプリケーションを新しいGWTバージョンにアップグレードすることは、いくつかの依存関係があるため簡単ではありません。影響を受けるGWTのバージョンのリストがありますか? @DanielK。 –

+0

コンパイラだけではなく、具体的にはリンカです。最新のgwtで壊れたリンカを使用することも、gwt 2.0上で動作するリンカを使用することもできます。これで、GWT 2.5.1のすべての_built-in_リンカのソースをすばやく見直しましたが、すべての関数のtry/catchラッパーを発行していないようですので、カスタムリンカーを使用するか、 GWTの一部になる –

関連する問題