コアの問題はここで見ることができますhttp://jsfiddle.net/Raynos/UxrVQ/ IE が確認せずに window.hiya を上書きする理由をまだ調べていません。
[編集]
仕様書より。38ページ:
コード内の VariableDeclaration または VariableDeclarationNoIn ごとに、名前が VariableDeclaration または VariableDeclarationNoIn の識別子である変数オブジェクトのプロパティを作成します。その値は未定義で、属性はコードのタイプによって決まります。宣言された変数の名前を持つ変数オブジェクトのプロパティが既に存在する場合、プロパティの値とその属性は変更されません。
考えられる説明は、変数を宣言するときにグローバル スコープで IE がwindow
オブジェクトとグローバル スコープを区別することです。variable object
または、オブジェクトに直接プロパティを設定しても、window
オブジェクトに同じプロパティが設定されない場合がありvariable
ます。正式な JScript 仕様を見つけることができたり、IE のソースがあちこちに転がっている場合は、その癖が何であるかを正確に突き止めることができます。
[/編集]
ウィンドウオブジェクトへのプロパティの書き込みが変数宣言であるかどうかの問題であると指摘した@TimDownと@JuanMendesに感謝します。
問題:
変数宣言はブロックの先頭に移動されます。コードが死んでいても。IE では何らかの理由で hiya をローカル変数として宣言しますが、window に同じ名前のプロパティが格納されているにもかかわらずです。
説明:
何が起こっているかというと、hiya という変数を宣言しています。var ステートメントは自動的にブロックの先頭に削除されます。if ステートメントはブロックではなく、関数です。したがって、コードがブロックで実行されない場合でも、変数は宣言されます。
firefox では、window.hiya が hiya の宣言であることを認識します。
IE では、2 番目のスクリプトの宣言によって上書きされます。
実際に何をしているのか
ファイアフォックスの場合:
// script block 1
var hiya; // window.hiya counts as a declaration
window.hiya = "hiya"; // set
// script block 2
if (false) hiya = 1;
document.write(...)
IE の場合:
// script block 1
window.hiya = "hiya";
// script block 2
var hiya; // redeclared here because window.hiya "isn't" a declaration
if (false) hiya = 1;
document.write(...)
解決策は単に名前空間です。2 つの場所で同じ名前を使用し、2 つの異なる名前でアクセスしています。別の名前を使用するか、クロージャを使用してローカル スコープを指定してください。