2011-08-06 16 views
32

"if"ステートメントで宣言され、割り当てられた変数は、 "if"ブロック内または関数全体でのみ表示されますか?IFステートメントのjavascript変数スコープ

私は次のコードでこれを正しく実行していますか? (動作しているようですが、 "var構造"を複数回宣言することは厄介なようです)どんなクリーナーソリューションでも?

function actionPane(state) { 
    if(state === "ed") { 
     var structure = { 
      "element" : "div", 
      "attr" : { 
       "class" : "actionPane" 
      }, 
      "contains" : [{ 
       "element" : "a", 
       "attr" : { 
        "title" : "edit", 
        "href" : "#", 
        "class" : "edit" 
       }, 
       "contains" : "" 
      }, { 
       "element" : "a", 
       "attr" : { 
        "title" : "delete", 
        "href" : "#", 
        "class" : "delete" 
       }, 
       "contains" : "" 
      }] 
     } 
    } else { 
     var structure = { 
      "element" : "div", 
      "attr" : { 
       "class" : "actionPane" 
      }, 
      "contains" : [{ 
       "element" : "a", 
       "attr" : { 
        "title" : "save", 
        "href" : "#", 
        "class" : "save" 
       }, 
       "contains" : "" 
      }, { 
       "element" : "a", 
       "attr" : { 
        "title" : "cancel", 
        "href" : "#", 
        "class" : "cancel" 
       }, 
       "contains" : "" 
      }] 
     } 
    } 
    return structure; 
} 
+0

このようにすることもできます: 'if(state ===" ed "){} {return {...}} else {return {...}}'変数を使用する代わりに、 –

答えて

35

1)Variables are visible for the whole function scope。したがって、一度だけ宣言してください。

2)あなたの例では、変数を2回宣言しないでください。私は、ただ、後で値を設定し、関数の先頭で変数を宣言お勧めします:

function actionPane(state) { 
    var structure; 
    if(state === "ed") { 
     structure = {  
      ... 

はJavaScriptに優れたフィードバックのために、私は非常にダグラス・クロックフォードによってJSLintを使用することをお勧めします。あなたのコードで一般的なエラーをスキャンし、クリーンアップの提案を探します。

小さな本を読むこともお勧めしますJavaScript:良い部品。メンテナンス可能なJSコードを書くためのヒントがたくさんあります。

+0

@ WebWanderer - これはES6にのみ適用されますが、素晴らしいですが、クライアント側でコンパイラを使用する必要があります。 ES5以降では、グローバルレベルまたは機能レベルのスコープ以外はサポートされていません。 – OverZealous

+0

誰もがJSLintの代わりにJSHintを使用していると思います。 –

+0

@KevinWheelerこれはやや古い答えですが、ES6以降で作業している人なら誰でも[ESLint](http://eslint.org/)に移行する方がずっと良いでしょう。 – OverZealous

31

JavaScriptはない「ブロックスコープ」を持っていない、それが唯一の関数スコープを持っています - if文(またはいずれかの条件ブロック)内で宣言された変数は、外側のスコープに「掲揚」されるように。

if(true) { 
    var foo = "bar"; 
} 
alert(foo); // "bar" 

これは実際の経験から、鮮明な画像を描画(やインタビューで起動します:)

var foo = "test"; 
if(true) { 
    alert(foo); // Interviewer: "What does this alert?" Answer: "test" 
    var foo = "bar"; 
} 
alert(foo); // "bar" Interviewer: Why is that? Answer: Because JavaScript does not have block scope 

関数スコープは、JavaScriptで、一般的に閉鎖を指します。

var bar = "heheheh"; 
var blah = (function() { 
    var foo = "hello"; 
    alert(bar); // "heheheh" 
    alert(foo); // "hello" (obviously) 
}); 

blah(); // "heheheh", "hello" 
alert(foo); // undefined, no alert 

この関数の内部スコープは、それが含まれている環境にアクセスできますが、その逆もありません。

あなたの2番目の質問に答えるために、すべての条件を満たす「最小限の」オブジェクトを最初に構築し、満足している/満たしている特定の条件に基づいて拡張または変更することによって最適化を達成できます。

+6

Javascriptにはブロックスコープがあります。 let myVar = "最初に見てください!" '[let'キーワードをチェックしてください](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) – WebWanderer

+0

@WebWandererはここ2015年12月にはほとんどサポートされません。この回答は2011年8月に投稿されました。 – trex005

+0

@ trex005そうです、そうです。技術的には、それはまだサポートされていませんが、ECMA 6になります。私のコメントは、4年以上で答えを見つけられていないOPのためのものではなく、今。希望的な発想として私の発言を取る。 – WebWanderer

2

if文内で宣言された変数は、同じ関数内に存在する限り、利用可能です。

var structure = { 
    "element" : "div", 
    "attr" : { 
     "class" : "actionPane" 
    }, 
    "contains" : [{ 
     "element" : "a", 
     "attr" : { 
      "title" : "edit", 
      "href" : "#", 
      "class" : "edit" 
     }, 
     "contains" : "" 
    }, { 
     "element" : "a", 
     "attr" : { 
      "title" : "delete", 
      "href" : "#", 
      "class" : "delete" 
     }, 
     "contains" : "" 
    }] 
} 

if(state != "ed") { 
    // modify appropriate attrs of structure (e.g. set title and class to cancel) 
} 
2

が宣言され、「IF」文で割り当てられた変数です:あなたのケースでは

、最良の方法は、構造体を宣言して、いずれの場合も、異なるオブジェクトの一部を変更することであろうその "if"ブロック内または機能全体の中にのみ が表示されますか?JavaScriptで

、すべての変数は、どちらか

  • グローバルスコープ
  • ローカルスコープ(全体機能)です - Javascriptが変数を持つ唯一の利用可能な「ブロックスコープ」を持っていません。ローカルスコープの小さなブロック(関数)

私は次のコードでこれを正しく実行していますか? (動作しているようですが、 "var構造体"を複数回宣言することは厄介なようです)任意のクリーナー ソリューションですか?

はい。より洗練された解決策は、基本クラスstructureを作成し、それぞれの場合に異なるものを変更することです。

+0

Javascriptにはクラスがありません。 –

+1

@Tomalak:Javascript *は、しかし、クラスに匹敵するオブジェクトを持っています。 – foxy

+0

Javascriptにはオブジェクトがあります。しかし、そのOOPモデルはプロトタイプベースであり、クラスベースではありません。 –

3

のECMAScript 2015(ES6)は、最終的にはJavaScriptが回避策を使用することなく、適切なブロックスコープを達成するためにできる2つの新しいキーワード、口語構文が含まれます。

  1. let
  2. const
関連する問題