37

この JavaScript スニペットを実行しようとしているとします。宣言されていない vars とメソッドが上記の他の場所で宣言されていると仮定し、boolean-true に評価されますsomethingsomethingElse

try {
    if(something) {
        var magicVar = -1;
    }

    if(somethingElse) {
        magicFunction(magicVar);
    }
} catch(e) {
    doSomethingWithError(e);
}

私の質問は次のとおりです:スコープは何ですか?私が行ったようにmagicVarそれを渡しても大丈夫ですか?magicFunction

4

6 に答える 6

73

Javascriptがこれをどのように処理するかについての他の良い答えがたくさんありますが、私は状況varに対処すると思いました...let

変数がブロックlet内で定義されている場合、 (または) ブロックtry内のスコープには含まれません。囲んでいるブロックで定義する必要があります。catchfinally

たとえば、次のコード ブロックでは、コンソール出力は「Outside」になります。

let xyz = "Outside";

try {
    let xyz = "Inside";

    throw new Error("Blah");
} catch (err) {
    console.log(xyz);
}
于 2016-09-30T19:07:20.717 に答える
28

Javascript には関数スコープがあります。つまりmagicvar、ステートメントが実行されなくても、宣言されている関数の最初からその関数の最後まで存在します。これを可変巻き上げといいます。同じことが関数宣言でも起こり、これは関数巻き上げと呼ばれます。

変数がグローバル スコープで宣言されている場合は、すべてのユーザーに表示されます。これが、Javascript でグローバル変数が悪と見なされる理由の一部です。

何にも割り当てられていないため、あなたの例は false の場合に渡さundefinedれます。magicFunctionsomethingmagicVar

これは技術的に有効な Javascript ですが、一般的にスタイルが悪いと考えられており、jsLint のようなスタイル チェッカーを通過しません。このような非常に非直感的な Javascript は、エラーなしで実行されます

alert(a); //alerts "undefined"
var a;

POP QUIZ : 次のコードは何をしますか?

(function() {
  x = 2;
  var x;
  alert(x);
})();
alert(x);
于 2012-05-04T02:03:57.027 に答える
6
  • JavaScript では、関数のみが新しいコンテキストを作成します -closure.
  • 変数のすべての定義は、実際にはそのスコープの最上部での変数の宣言であり、定義がある場所での代入です。

変数

  • 関数スコープ
  • その機能の頂点に引き上げる
  • 同じスコープ内の同じ名前の再宣言はノーオペレーションです

MDN スコープ チート シートを読みたいと思うかもしれません

次のようなhoistingこともできます。

function bar() {
    var x = "outer";

    function foo() {
        alert(x); // {undefined} Doesn't refer to the outerscope x
        // Due the the var hoising next:        
        x = 'inner';
        var x;
        alert(x); // inner

    }
    foo();
}

bar();​

bar();​

デモ

したがって、foo関数は次のように変換されます。

function foo() {
    var x;
    alert(x); // {undefined} Doesn't refer to the outerscope x
    // Due the the var hoising next:        
    x = 'inner';
    alert(x); // inner
}​

私の質問は次のとおりです。magicVar のスコープは何ですか?私が行ったようにそれを magicFunction に渡しても問題ありませんか?

定義OK ...、はい、コードは有効ですが、変数宣言が一番上にある場合よりも読みにくくなります。それだけです。

于 2012-05-04T02:03:41.533 に答える
4

JavaScript の「巻き上げ」(google it) により、変数宣言コードは次のように変換されます。

function yourFunction() {
  var magicVar;
  try {
      if(something) {
          magicVar = -1;
      }

      if(somethingElse) {
          magicFunction(magicVar);
      }
  } catch(e) {
      doSomethingWithError(e);
  }

} //end of your function

「巻き上げ」は、すべての変数宣言を関数の先頭に移動します。SomagicVarは関数内のどこでも使用できますが、値を指定するまでは未定義です。

変数には関数スコープがあります。

于 2012-05-04T02:05:42.280 に答える
1

ではvar、変数が宣言されている場所に関係なく、または実際にステートメントに到達した場合でも、変数は関数の最初から最後まで存在します。ただし、undefined別の値が割り当てられるまではそのままです。

したがって、あなたの場合、somethingが false であるが true の場合、最初の引数が であるsomethingelseと呼び出します。magicFunctionundefined

letJavascript 1.9 で作成され、(今日、2012 年 5 月 3 日現在、私の知る限り) Firefox でのみ利用可能なキーワードは、おそらく慣れ親しんだスコープ付きセマンティクスで変数を宣言します。

于 2012-05-04T02:02:30.757 に答える