web-dev-qa-db-ja.com

IFステートメントのjavascript変数スコープ

「if」ステートメントで宣言および割り当てられた変数は、その「if」ブロック内または関数全体内でのみ表示されますか?

次のコードでこれを正しくやっていますか? (動作しているようですが、「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;
}
48
Joseph

1) 変数は関数スコープ全体に表示されます 。したがって、それらを一度だけ宣言する必要があります。

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

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

JavaScriptに関する優れたフィードバックを得るには、Douglas Crockfordによる JSLint を使用することを強くお勧めします。一般的なエラーについてコードをスキャンし、クリーンアップの提案を見つけます。

また、小さな本JavaScript:The Good Partsを読むことをお勧めします。保守可能なJSコードを記述するための多くのヒントが含まれています。

47
OverZealous

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番目の質問に答えるには、すべての条件を満たす「最小」オブジェクトを最初に構築し、次に、満たされた特定の条件に基づいてオブジェクトを増強または変更することにより、最適化を達成できます。

41
karim79

ECMAScript 2015(ES6)には、回避策や口語構文を使用せずにJavaScriptが適切なブロックスコープを達成できるようにする2つの新しいキーワードが含まれています。

  1. let
  2. const
3
TheDarkIn1978

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
Eric Conner

「if」ステートメントで宣言および割り当てられた変数は、その「if」ブロック内または関数全体内でのみ表示されますか?

Javascriptでは、すべての変数は

  • グローバルスコープ
  • ローカルスコープ(全体関数)-Javascriptには、ローカルスコープ(関数)の小さなブロックでのみ変数が使用できる「ブロックスコープ」がありません

私はこれを次のコードで正しくやっていますか? (動作しているようですが、「var構造」を複数回宣言するのは厄介なようです)よりクリーンなソリューションはありますか?

はい。よりクリーンなソリューションは、structureの基本クラスを構築し、それぞれのケースで異なるものを変更することです。

2
foxy