4

ブラウザ(IE8)のJSONオブジェクトは文字列をJSONに解析するために使用できなかったため、プロジェクトでjson2.jsを使用する必要がありました。

json2.jsを実行しましたが、変数宣言に疑問があります。

JSONグローバル変数はjson2.jsで次のように宣言されます

var JSON;
if(!JSON){
    JSON={};
}

var JSON;グローバルJSONオブジェクトに対する宣言の効果は何ですか。宣言が任意のブラウザー(IE8 / IE7)のグローバルJSONオブジェクトをオーバーライドする必要があることを願っています。しかし、驚いたことに、グローバルオブジェクトが使用可能な場合はオーバーライドされません。変数の定義/開始のみがグローバル変数をオーバーライドしますか?明確にしてください。

4

4 に答える 4

3

varキーワードは、囲んでいる関数または(ここのように)ウィンドウに変数があることを確認しますが、変数を初期化しません。

実際、順序は実際には影響しません。

例としてこのコードを見てください:

a = 3;
var a;
alert(a);

「3」を警告します。

したがって、表示するコードのvar宣言は、テストでエラーが発生しないことを保証し、既存の値を削除しません。

javascriptの一般的なエラーは、関数内に複数のvar宣言があり、var宣言の前に設定された値に驚かされることであるため、これを覚えておくとよいでしょう。たとえば、これを実行します。

if (true) {
    ​a = 3;
}
// lot of code, at a different level
if (true) {
    var a;
    if (433/43==3) a=true;
    if (a) alert('should not happen');
};
​

はい、変数はブロックではなく関数にアタッチされています...

于 2012-05-02T18:28:12.893 に答える
3

変数宣言ごとに(初期化ではありません!)。次のことが起こります (セクション#10.5):

8.コード内のVariableDeclarationおよびVariableDeclarationNoIn dごとに、ソース テキストの順に実行します。

  1. dnをdの識別子とします
  2. varAlreadyDeclaredを、引数としてdnを渡してenv のHasBinding具象メソッドを呼び出した結果とします。
  3. varAlreadyDeclaredfalseの場合、
    1. env のCreateMutableBinding 具象メソッドを呼び出し、 dnconfigurableBindingsを引数として渡します。
    2. 引数としてdnundefined、およびstrictを渡して、 env のSetMutableBinding 具象メソッドを呼び出します。

ご覧のとおり、 が検出されるたびvar xに、名前を持つ変数がx環境に既に存在するかどうかがテストされます。はいの場合は単に無視されますが、そうでない場合は変数が宣言され、 で初期化されundefinedます。

コードはグローバル スコープで実行されるため、グローバル スコープにJSON存在するかどうかをテストします。したがって、JSONすでに存在する場合var JSON;は無視されます。


この動作のテスト/説明に関するいくつかの考え:

JavaScript 実行のどの時点でグローバル オブジェクトが作成されるかはわかりませんが、他のすべてのスクリプトが評価される前に作成されると思います。つまり、変数宣言のJSONに存在し、値を持っています。これは、2 つのスクリプトを含める場合にのみシミュレートできるものです (インラインにすることもできます。それらは次々に評価されます)。

試す:

// script1.js
var foo = 'bar';

// script2.js
var foo;
if(!foo) {
    foo = 'baz';
}
alert(foo);

// include script2.js after script1.js

結果は?(詐欺師はここを見てください)。


単一のスクリプト ファイルにいるときはいつでも、すべての変数宣言が先頭に持ち上げられます。だからあなたが持っているなら

var foo = 'bar';
var foo;
if(!foo) {
    foo = 'baz';
}

スクリプトは実際には次のように実行されます。

var foo;
var foo;
foo = 'bar';
if(!foo) {
    foo = 'baz';
}

var foo;この時点ではまだ値がないため、2 番目が最初のものを上書きするかどうかを実際にテストすることはできません。したがって、これは上記の動作を示す良い例ではありません。

于 2012-05-02T18:36:07.463 に答える
0

これは選択肢ではないかもしれませんが、IE8 を互換モードに設定して、ネイティブの JSON オブジェクトを元に戻すこともできます。

// in your preinit page event
Response.AddHeader("X-UA-Compatible", "IE=8");

もう 1 つのオプションは、存在しない場合にのみ JSON 変数を作成することです。

var JSON = JSON || {};
于 2012-05-02T18:27:55.400 に答える
-1

そのコードブロックを実行するときにグローバルスコープ内にいる場合、varJSONはグローバルJSONオブジェクトを未定義に上書きします。

他のスコープ(関数内など)にいる場合、効果はありません。

于 2012-05-02T18:26:46.020 に答える