1

前もって申し訳ありませんが、これは以前に StackOverflow で議論された可能性があります。これが何と呼ばれているのか分からないため、満足のいく答えを見つけることができませんでした。

しかし、私は JavaScript を学んでいて、「Eloquent JavaScript」という本を読んでいます。そこで、次のコードを見つけました。これは、ユーザーが名前を入力するまで繰り返しプロンプトを表示します。

while (!input) {
    var input = prompt("Who are you?");
}

エラーが発生する代わりに、これが実際に機能する理由がわかりません。条件式が評価されている時点では、inputと呼ばれる変数は存在しません。私がそれを正しく理解していれば、通常はそれ以上の実行を妨げる評価はありません。ただし、 inputという変数を作成するwhileループ本体のステートメントは、まだ実行中です。

しかし、これは私を不安にさせたので、私はこれを試しました:

while (!bool) {
    console.log("Hi");
    var bool = true;
}

これはさらに奇妙です。条件式に関しても同じ問題です。条件の評価、ループ本体のスコープ内でboolが作成されています。次に、boolは常に true に設定されますが、コードは 1 回実行されます。つまり、Hiは 1 回出力されます。

私は混乱しており、助けていただければ幸いです。;)

4

4 に答える 4

6

これは、Javascript の小さな奇抜さの 1 つです。var x =覚えておくべき重要なことは、Javascript では、コード内の が現れる場所で変数が作成されるとは限らないということです。それらは常にスコープの一番上に作成されます。これは、それらを含む関数の先頭、またはグローバル スコープの先頭 (作業しているスコープの場合) を意味します。これはホイストと呼ばれます。

したがって、コードは次のようになります。

function doStuff() {
    while (!bool) {
        console.log("Hi");
        var bool = true;
    }
}

しかし、次のように実行されます。

function doStuff() {
    var bool = undefined;
    while (!bool) {
        console.log("Hi");
        bool = true;
    }
}

(Javascript にはブロック スコープのようなものがないことに注意してください。)

初めて、boolですundefined!undefinedですtrueので、条件はパスします。その後、boolistrueであるため、条件は失敗します。input最初の例と同様の話です。

変数は、宣言されている場所に関係なく、常にスコープの一番上に作成されます。このため、スコープの先頭で変数を宣言することをお勧めする場合があります。これは、Javascript が変数をスコープの先頭にあると見なすためです。これにより、引用したような驚きを防ぐことができます。

于 2013-02-04T22:54:37.317 に答える
1

JavaScriptには、変数が、それを囲むブロック内ではなく、宣言された関数のレベルでスコープされるという珍しい特性があります(C ++やJavaなどの言語の場合のように)。これは、関数の本体内のどこで変数が宣言されているかに関係なく、関数内で宣言された変数が、関数の実行を開始した瞬間にスコープ内にあることを意味します。この動作は、 「巻き上げ」または「持ち上げ」と呼ばれることもあります。

多くのJavaScriptプログラマーは、宣言する前にスコープ内に変数があるという奇妙な特性を回避するために、関数の最初に関数内のすべての変数を宣言することをお勧めします。

JavaScriptのさらに不幸な振る舞いは、グローバル変数を設定するだけでその場で定義できることです。したがって、プログラムにinputという名前の変数がない場合、次のコードは次のようになります。

input = prompt("Who are you?");

inputという名前のグローバル変数を作成し、promptメソッドによって返される文字列を割り当てます。これは、あらゆる種類のデバッグが困難な副作用につながる可能性があるため、不適切な方法と見なされます。

于 2013-02-04T23:02:43.987 に答える
1

JavaScript では、変数を明示的に宣言する必要はありません。明示的に宣言する前に、変数にアクセスしたり、変数に値を代入したりできます。(lonesomeday が説明したように、それにはもっと多くのことがあります - 簡単に言いたかっただけです)。

明示的に宣言する前に変数にアクセスすると、値はundefinedになります。

したがって、自分で確認したい場合は、コード内で のalert(input);前にを使用してみてください。while

于 2013-02-04T22:54:18.850 に答える
0

実現する2ビットがあります。最初、inputは未定義であり、これは「偽の」値であるため、!inputはtrueと評価されます。次に気付くのは、varinputまたはvarboolが割り当てられると、それらはループと同じスコープ(つまり、ループのすぐ外側)で有効になるため、ループが2回繰り返されると、変数が設定されます。入力の場合、nullまたは未定義のものはすべて偽物と見なされるため、入力に値が設定されると、ループは終了します。これは、次のコードで確認できます。

        while(!bar) {
        console.log('1', bar);
        var bar = true;
        console.log('2', bar);
    }
    console.log('3', bar);
于 2013-02-04T23:02:54.807 に答える