67

Are variables declared and assigned in an "if" statement visible only within that "if" block or within the whole function?

Am I doing this right in the following code? (seems to work, but declaring "var structure" multiple times seems awkward) any cleaner solutions?

    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;
}
starball
  • 20,030
  • 7
  • 43
  • 238
Joseph
  • 117,725
  • 30
  • 181
  • 234

5 Answers5

62

1) Variables are visible for the whole function scope. Therefore, you should only declare them once.

2) You should not declare the variable twice in your example. I'd recommend declaring the variable at the top of the function, then just setting the value later:

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

For excellent feedback on JavaScript, I highly recommend using JSLint by Douglas Crockford. It will scan your code for common errors, and find suggestions for cleanup.

I also recommend reading the small book JavaScript: The Good Parts. It contains a lot of tips for writing maintainable JS code.

Community
  • 1
  • 1
OverZealous
  • 39,252
  • 15
  • 98
  • 100
  • @WebWanderer - that only applies to ES6, which is awesome, but requires a compiler to be used client-side. ES5 and older does not support anything other than global or function-level scope. – OverZealous Apr 16 '15 at 23:49
  • I think everyone uses JSHint instead of JSLint now days. – Kevin Wheeler Jun 16 '15 at 22:57
  • 2
    @KevinWheeler This is a rather old answer, but anyone working on ES6 or newer would be much better off migrating to [ESLint](http://eslint.org/). – OverZealous Jun 17 '15 at 00:40
56

NOTE: This answer is from 2011. It's not possible to declare a variable with either let or const and have its scope remain within a conditional if block.


JavaScript has no "block scope", it only has function scope - so variables declared inside an if statement (or any conditional block) are "hoisted" to the outer scope.

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

This actually paints a clearer picture (and comes up in interviews, from experience :)

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

Function scope, in JavaScript, typically refers to closures.

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

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

The inner scope of the function has access to the environment in which it is contained, but not the other way around.

To answer your second question, optimisation can be achieved by initially constructing a 'minimal' object which satisfies all conditions and then augmenting or modifying it based on particular condition(s) which has/have been satisfied.

Alan W. Smith
  • 24,647
  • 4
  • 70
  • 96
karim79
  • 339,989
  • 67
  • 413
  • 406
  • 12
    Javascript does have block scope. You can declare variable within an `if statement` using `let myVar = "Look it up first!"` [Check out the `let` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) – WebWanderer Apr 16 '15 at 20:42
  • 1
    @WebWanderer let is hardly supported here in December of 2015, this answer was posted in Aug of 2011. – trex005 Dec 04 '15 at 18:04
  • 4
    @trex005 Yea, I get that. Technically, it is not supported yet, but will be with ECMA 6. My comment isn't for the OP, who hasn't found their answer in over four years, but is instead for others passing through this post wondering how to do this now. Take my comment as wishful thinking. – WebWanderer Dec 04 '15 at 21:51
  • typo? not possible -> now possible? – starball Sep 01 '23 at 22:39
6

ECMAScript 2015 (ES6) includes two new keywords that finally allow JavaScript to accomplish proper block scoping without the need to use work-around, colloquial syntax:

  1. let
  2. const
Chunky Chunk
  • 16,553
  • 15
  • 84
  • 162
3

are variables declared and assigned in an "if" statement visible only within that "if" block or within the whole function?

In Javascript, all variables are either

  • global scope
  • local scope (entire function) - Javascript doesn't have a "block scope" where variables are only available with a smaller block of the local scope (function)

am i doing this right in the following code? (seems to work, but declaring "var structure" multiple times seems akward) any cleaner solutions?

Yes. A cleaner solution might be to build a base class of structure, and modify what is different in each case.

foxy
  • 7,599
  • 2
  • 30
  • 34
2

Variables declared inside the if statement will be available outisde as long as they reside in the same function.

In your case, the best way would be to declare structure and then modify the parts of the object that differ in either case:

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)
}
Eric Conner
  • 10,422
  • 6
  • 51
  • 67