4

次のコード スニペットでは、グローバル変数を宣言し、関数内での存在を確認しています。

<script>
x = 5;
$(function() {
   var x = x || 3;
   console.log(x); // prints 3
});
</script>

これは異なる動作をします:

<script>
x = 5;
$(function() {
   var y = x || 3;
   console.log(y); // prints 5
});
</script>

最初の例では、内部スコープの変数宣言が x が既にグローバル スコープに存在することを検出し、その値を取ることを期待しています。最初の例はなぜ 3 なのですか?

Specifically I recently wrote some code that checks var _gaq = _gaq || [] in a jQuery ready scope and was confused when nothing was getting pubbed to Analytics.

4

3 に答える 3

3

x間違った範囲で探しています。変数の巻き上げにより、チェックが行われる前に値を持つvar xローカル変数を実際に定義しました。xundefinedx || 3

var x = x || 3;

実際には:

var x = undefined;
x = x || 3;

オブジェクトを探すように変更するだけですxwindow

var x = window.x || 3;
于 2012-07-16T19:41:35.510 に答える
1

最初の例では3をログに記録します。 any variable that is initialized inside a function using the var keyword will have a local scope. If a variable is initialized inside a function without var, it will have a global scope.

したがって、最初のケースでは、ローカルxが割り当てられると、初期化されていないため、3が割り当てられます。

2番目のケースでは、関数内に宣言がないxため、グローバル変数を参照します。xx

代わりに、これを試してみると

<script>
x = 5;
$(function() {
   x = x || 3;
   console.log(x);
});
</script>

また

<script>
x = 5;
$(function() {
   var x = window.x || 3;
   console.log(x);
});
</script>

期待どおりの結果が得られます5

さらに、Cとそのファミリ(ブロックレベルのスコープを持つ)とは異なり、JavaScriptには関数レベルのスコープがあります。ifステートメントなどのブロックは、新しいスコープを作成しません。関数のみが新しいスコープを作成します。

だから私が次のようなものを書くとしたら

#include <stdio.h>
int main() {
    int x = 1;
    printf("%d, ", x); // 1
    if (1) {
        int x = 2;
        printf("%d, ", x); // 2
    }
    printf("%d\n", x); // 1
}

出力:1,2,1

と比較して

var x = 1;
console.log(x); // 1
if (true) {
    var x = 2;
    console.log(x); // 2
}
console.log(x); // 2

出力:1,2,2

JavaScriptのスコープとホイストに関するこの優れたブログ投稿を読んで、理解を深めてください。

于 2012-07-16T19:43:50.610 に答える
0

関数内のvar xは x が関数に対してローカルであることを宣言しているため、x || 3x 内ではグローバル x ではなく、初期化されていないため未定義です。

関数には x ローカルがないため、var y = x || 3;x はグローバル x です。

于 2012-07-16T19:38:56.493 に答える