51

私はJSLintを使って自分のJavaScriptに嫌悪感を抱かせてきました。ところで、それは素晴らしいです。よくわからないチェックが一つありますので、ご意見をお聞かせください。

jslint.comから:

ブロック スコープを持つ言語では、通常、最初に使用する場所で変数を宣言することをお勧めします。ただし、JavaScript にはブロック スコープがないため、関数のすべての変数を関数の先頭で宣言する方が賢明です。関数ごとに 1 つの var ステートメントを使用することをお勧めします。

太字の最後の文は実際に何を言っていますか? このように複数の変数を宣言する必要があると思いますか?

var foo = 1, bar = 2;

そして、「賢明な」部分は、エラーを思いとどまらせるための単なるプログラミングスタイルですか、それともそれ以上のものがありますか?

ご協力いただきありがとうございます。

4

4 に答える 4

72

問題は、気づいているかどうかにかかわらず、javascript が目に見えない形ですべての var 宣言を関数スコープの先頭に移動することです。

したがって、このような機能がある場合

var i = 5;
function testvar () {
     alert(i);
     var i=3;
}
testvar();

アラート ウィンドウには undefined が含まれます。内部的には、次のように変更されているためです。

var i = 5;
function testvar () {
     var i;
     alert(i);
     i=3;
}
testvar();

これは「巻き上げ」と呼ばれます。crockford が var 宣言を一番上に置くことを強く主張する理由は、それによって、目に見えない予期しない動作が発生するのではなく、実行しようとしていることにコードが視覚的に一致するようになるからです。

于 2009-08-05T23:27:45.963 に答える
8

基本的に JavaScript ブロック ( { ... }) は新しいスコープを導入しません。関数スコープしかないため、他のステートメントにはスコープが作成されません。

関数内のどこかに導入された変数は、関数内のどこからでも見えます。

例えば:

function myFunction(){
  var one = 1;

  if (one){
    var two = one + 1;
  }

  (function () {
    var three = one + two;
  })();

  // at this point both variables *one* and *two* are accessible but 
  // the variable *three* was declared in the scope of a inner function
  // and is not accessible  at this point.
}

ブロック スコープを持つ言語では、最初に使用する時点で変数を宣言することをお勧めしますが、JavaScript にはブロック スコープがないため、関数のすべての変数を関数の先頭で宣言することをお勧めします。

この記事をチェックしてください。

于 2009-08-05T23:05:31.967 に答える
6

ブロックスコープの欠如は、以下のコードを説明しています:

var a = 1;
if (something) {
    var a = 2;
}

alert(a); // Alerts "2"

ほとんどの C スタイル (構文のような) 言語では、var a = 2定義はifブロックのスコープに対してのみ 'a' を定義します。関数の先頭で単一の var ステートメントを使用すると、上記のように常に明白であるとは限らず、C/C#/Java プログラマーにとって予期しない、Javascript のこの癖を回避するのに役立ちます。

于 2009-08-06T02:23:32.980 に答える
4

はい、関数の先頭ですべての変数を宣言することを意味します。1 行で行うか、複数行で行うかは選択の問題です。

理由は、あなたが言及した段落で説明されています。Javascript 変数には、関数レベルのスコープしかありません。if/while/for ブロック内で同じ変数を宣言すると、ブロックは新しいスコープを持たないため、新しい値で上書きされます。これは、Java などの言語とは異なります。このような驚きを避けるために、関数で使用するすべての変数を関数の先頭で宣言して、誤って「再宣言」しないようにします。

于 2009-08-05T23:09:51.223 に答える