8protons
8protons

Reputation: 3959

Is there a reason why the JavaScript console or WebStorm IDE didn't warn me about this mistake?

Below is some code that wasn't behaving as expected. The middleLayerChoice being passed into the function that holds this code is '2MM'. Looking at it now, the error is obvious, but this was nested into a longer conditional branch (I'll be refactoring to Switch statements) so it took me a few trial-and-error runs of plugging in some console.log('line x') statements. The broken code is below:

if (middleLayerChoice === '1MM') 
     if (buttonID === 'xmm2mm') {
          console.log('MID = 1mm, TOP = 2mm');
          return ('resources/OptionalTopCovers/M_2_1.js');
     }                
     else if (buttonID === 'xmm3mm') {
          console.log('MID = 1mm, TOP = 3mm');
          return ('resources/OptionalTopCovers/M_3_1.js');
     }
else if(middleLayerChoice === '2MM') {
     if (buttonID === 'xmm2mm') {
          console.log('MID = 2mm, TOP = 2mm');
          return ('resources/OptionalTopCovers/M_2_2.js');
     }
     else if (buttonID === 'xmm3mm') {
          console.log('MID = 2mm, TOP = 3mm');
          return ('resources/OptionalTopCovers/M_3_2.js'); 
     }
}
...
...
else {
     console.log('getNewObject case 3 failed');
}

What I was missing was an entire set of braces:

if (middleLayerChoice === '1MM') **{**
     if (buttonID === 'xmm2mm') {
          console.log('MID = 1mm, TOP = 2mm');
          return ('resources/OptionalTopCovers/M_2_1.js');
     }
**}**    

Once we're all done giggling at my amateur mistake, could anyone tell my why the JavaScript console or WebStorm didn't warn me about this error? My code didn't crash, my else statement didn't log the error I wanted, and the code kept on running like things were okay (what was being returned was an undefined value).

I feel like compilers from other languages would have screamed at me for this mistake; so what's the reasoning behind both JavaScript and WebStorm ignoring this?

Upvotes: 0

Views: 121

Answers (3)

Shomz
Shomz

Reputation: 37701

Because it's technically legit. You can have a one-line statement block. So, that's why the code didn't complain, although that's definitely not what you wanted because this:

if (middleLayerChoice === '1MM') 
     if (buttonID === 'xmm2mm') {
          console.log('MID = 1mm, TOP = 2mm');
          return ('resources/OptionalTopCovers/M_2_1.js');
     }                
     else if (buttonID === 'xmm3mm') {
          console.log('MID = 1mm, TOP = 3mm');
          return ('resources/OptionalTopCovers/M_3_1.js');
     }
else if(middleLayerChoice === '2MM') {
     if (buttonID === 'xmm2mm') {
          console.log('MID = 2mm, TOP = 2mm');
          return ('resources/OptionalTopCovers/M_2_2.js');
     }
     else if (buttonID === 'xmm3mm') {
          console.log('MID = 2mm, TOP = 3mm');
          return ('resources/OptionalTopCovers/M_3_2.js'); 
     }
}
...
...
else {
     console.log('getNewObject case 3 failed');
}

got interpreted as (note the indentation, added the braces for clarity):

if (middleLayerChoice === '1MM') {
     if (buttonID === 'xmm2mm') {
          console.log('MID = 1mm, TOP = 2mm');
          return ('resources/OptionalTopCovers/M_2_1.js');
     }                
     else if (buttonID === 'xmm3mm') {
          console.log('MID = 1mm, TOP = 3mm');
          return ('resources/OptionalTopCovers/M_3_1.js');
     }
     else if(middleLayerChoice === '2MM') {
        if (buttonID === 'xmm2mm') {
          console.log('MID = 2mm, TOP = 2mm');
          return ('resources/OptionalTopCovers/M_2_2.js');
        }
        else if (buttonID === 'xmm3mm') {
          console.log('MID = 2mm, TOP = 3mm');
          return ('resources/OptionalTopCovers/M_3_2.js'); 
        }
     }
     ...
     ...
     else {
         console.log('getNewObject case 3 failed');
     }
}

causing only middleLayerChoice === '1MM' to actually be able to "go in", to check for buttonID.

Many thanks to @apsillers for helping me correct this.

Upvotes: 5

Odalrick
Odalrick

Reputation: 645

As others have said; there was no error, without the curly-braces the if applies to the statement, with them it applies to the block.

To avoid the problem in the future, you can reformat your code (Ctrl-Alt-L or search for it with Ctrl-Shift-A) Webstorm will automatically change indentation and make it obvious what lines belong to which if-block.

To make the problem even more obvious in the future, you can go into Settings>Editor>Code Style>JavaScript, the tab Wrapping and Braces and change "force braces" to "Always" for if, while, for and do.

Compared to other languages, JavaScript support in Webstorm is worse; good, but not on the level of Java or even PHP. Probably because JavaScript is very flexible, not in any way statically typed and has lacked oversight for most of it's lifetime. Adding docblocks help a lot.

There are a lot of other tools that help as well, like ESLint and TypeScript; but setting them up can be more trouble than it's worth when you are a beginner.

Upvotes: 2

Quentin
Quentin

Reputation: 943108

JavaScript ifs can be followed by a block or a statement.

if (1)
    doSomething();
else
    doSomethingElse();
doSomethingInEitherCase();

… is valid, albeit frowned up, JS.

Tools such as JS Hint can alert you to syntax which is valid but which suffers from this kind of gotcha.

Upvotes: 3

Related Questions