27

この質問で申し訳ありませんが、この問題は私の一日を本当に台無しにしました。

次のコードは、必要に応じて10を警告します。

var globalId='10';  
function check(){  
    alert(globalId);  
}  
check();

しかし、この次のコードはundefinedを警告します:

var globalId='10';  
function check(){  
    alert(globalId); 
    var globalId; 
}  
check();

関数で変数をローカル変数として宣言すると、すでにグローバルとして宣言している場合、アラートにundefinedと表示されるのはどうしてでしょうか?

これは簡単な例ですが、元のコードでは、関数の開始の間に多くのことを行いました。その後、長い道のりで が定義されているかどうかを確認し、定義されていない場合globalIdは定義します。if(!globalId){var globalId;}これは、私のアラートがJavaScript が最初に関数全体を実行したかのように、関数の先頭に undefined が生成され、変数が宣言されている可能性があるかどうかを確認し、宣言されている場合はそれらを宣言するため、私のアラートは「宣言されていない」変数を指していました。

JavaScriptが関数を実行する前にすべての変数を「事前宣言」することが本当なら、条件が満たされていない条件で宣言された変数であっても、誰かが私に説明できますか?

4

6 に答える 6

24

JavaScript では、 HOISTINGと呼ばれるものがあることを知っておく必要があります。

これが本質的に意味することは、ローカル変数を宣言すると、変数宣言が自動的にスコープの先頭に運ばれるということです。

例えば:-

var globalId='10';
function check(){
alert(globalId); var globalId; }
check(); 

- への変更

var globalId='10';
function check(){
var globalId;
alert(globalId);}
check(); 

globalID にはまだ値が割り当てられていないため、出力では undefined が返されます。ローカル変数は、常に同じ名前のグローバル変数よりも優先されます。

于 2011-03-31T11:36:43.197 に答える
17

はい、関数内の任意の場所で宣言されたすべての変数は、その関数に対してローカルであり、関数のコード全体に存在します。これらは、同じ名前のグローバルに優先して使用されます。

https://developer.mozilla.org/en/JavaScript/Guide/Values,_Variables,_and_Literals#Variable_Scopeから:

JavaScript にはブロック ステートメントのスコープがありません。むしろ、ブロックが存在するコードに対してローカルになります。[...] JavaScript の変数に関するもう 1 つの珍しい点は、例外を取得せずに、後で宣言された変数を参照できることです。この概念は巻き上げとして知られています。JavaScript の変数は、ある意味で、関数またはステートメントの先頭に「持ち上げられた」または持ち上げられています。

于 2011-03-31T11:36:02.140 に答える
13

コードの 2 番目の部分では、ローカル変数がグローバル変数をマスクします。

var globalId='10';

function check() {
    // Your are defining a local variable in this function
    // so, the global one is not visible.
    alert(globalId);
    var globalId;
}

check(); 


yopurvarステートメントが関数の定義の最後にあるという事実は、何も変更しません。グローバル変数は、関数全体に対してマスクされます。

したがって、関数の実行全体で、globalId変数はグローバル変数ではなくローカル変数を参照します。

varただし、その関数の外側では、グローバル変数は引き続き存在します。ステートメントのために、関数の内側からは見えません。

于 2011-03-31T11:35:51.263 に答える
4

すでに述べたように、JavaScriptのスコープ規則に準拠して、ローカル変数は関数全体のグローバルをマスクします。ただし、グローバル変数にアクセスできる場合は、次のことを試してください

var globalId='10';

function check() {
    // Your are defining a local variable in this function
    // so, the global one is not visible.
    alert('Local : ' + globalId + ', Global : ' + window.globalId);
    var globalId;
}

check(); 
于 2011-03-31T11:43:34.813 に答える
0

あたかもJavascriptが最初に関数全体を実行したかのように、変数が宣言されている可能性があるかどうかを確認するだけです

これが多かれ少なかれ答えです。JavaScript インタープリターは、各スコープ内で変数宣言を探し、スコープの先頭に「移動」します。

于 2011-03-31T11:41:10.217 に答える
0

globalId関数スコープ内でNEW 変数を宣言するため、未定義であり、これは正しいです。いいえ、それはグローバル変数を殺すことではありません。呼び出しalert(globalId);後に追加することで確認できます。check();

于 2011-03-31T11:36:18.987 に答える