1

Because I'm used to C and Java, I've found Javascript's lack of block scope a little irksome. Sometimes I find myself wanting to declare and then immediately execute an inline function just to overcome this issue. For example:

... 

if (x == 0) { 
  (function () {
    var i;

    for (i = 0; i < 10; i++) {
      ...
    }
  })();
}

...

Otherwise, I feel the need to declare all of the variables for a function at the top of the scope, in order to avoid forgetting about the lack of block scope. But having a huge var statement at the beginning of a function looks clumsy to me.

The way I've shown above feels wasteful, but I don't have any idea of what it costs to declare inline functions in the first place. Is doing it this way a bad idea? Is there a better way to solve my qualm with Javascript's scoping?

Robz
  • 1,747
  • 5
  • 21
  • 35
  • 2
    Defining functions inside `if` clauses is a serious anti-pattern. and I *think* it's illegal in "strict" mode. – Pointy Mar 10 '13 at 04:04
  • It's an issue because you don't like var blocks-but in JavaScript, there are var blocks. Of course, if your methods are appropriately sized, you won't have many anyway. – Dave Newton Mar 10 '13 at 04:06
  • @Pointy: IIFEs aren't that big a deal. It's the function *statements* that are a problem. This code may well be illegal, though, since it doesn't have the definition in parentheses (which makes it a statement). – cHao Mar 10 '13 at 04:07
  • 2
    _"Is there a better way to solve my qualm with Javascript's scoping?"_ Yes, just get over it. You might enjoy the movie titled "Dr. Brendan or: How I Learned to Stop Worrying and Love Function Scoping." – Matt Ball Mar 10 '13 at 04:07
  • @cHao yes I should have said "declaring functions"; that's a syntax error anyway. – Pointy Mar 10 '13 at 13:49

2 Answers2

3

JavaScript scoping, short of ES5 features, is at the function level. It's like how C used to require you to declare variables before anything else; you just have to live with it.

Your code is not syntactically correct. You've got a statement that starts with the function keyword, but no function name; it's also followed by (). I assumed you're talking about a function declaration statement. If you're just instantiating a function as part of an expression, then scope doesn't really figure into that, at least external to the function.

Pointy
  • 405,095
  • 59
  • 585
  • 614
3

What's wrong with writing it as follows:

if (x === 0) { // you should always use === over == in JavaScript
    for (var i = 0; i < 10; i++) {
        // body
    }
}

Just because JavaScript doesn't support block scoping doesn't mean that you can't declare variables in block scopes.

You can declare variables anywhere. However they'll be visible everywhere in the scope of the function.

The only problem caused by the lack of block scoping in JavaScript is when you define a function inside a loop which accesses free variables (the infamous loop problem).

Read the following StackOverflow thread to wrap your head around it: JavaScript closure inside loops – simple practical example

JavaScript is simple. Way more simple than C or Java. It's a lot more sensible than Java too. Java is a pathetic language.

If you want the JavaScript community to be daggers against you then you're doing a wonderful job. Otherwise just embrace JavaScript. In the words of Douglas Crockford:

In my own practice, I have found that working with JavaScript has made me a better Java programmer because it introduced me to a useful set of dynamic techniques.

Source: A Survey of the JavaScript Programming Language

Community
  • 1
  • 1
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299