简体   繁体   中英

Is it wrong to declare a variable inside an if statement in Javascript?

I have a Sublimelinter installed in Sublime Text 2 and it's great. However it doesn't like the following code:

if(condition){
    var result = 1;
}else{
    var result = 2;
}
process(result);

It says for var result = 2; that result is already defined and for process(result); that it's used out of scope. Is it just mistaking the {} of the if statement for a more closed scope or should I really be doing it like this:

var result;
if(condition){
    result = 1;
}else{
    result = 2;
}
process(result);

No it is not "wrong"; it will get hoisted to the top of the nearest function definition, as per the ECMAScript specification.

Yes, your program "Sublimelinter" is incorrect to claim the variable is out of scope.

It is not wrong. If you get that error, you defined result earlier in your code.

You can also simplify your condition to this so you don't have to use result:

process( condition ? 1 : 2 );

Javascript doesn't have 'block-scoping' like many other languages. If it did, the variable result would not exist when you tried to call process(result) because it would not be possible to reference it outside of the {} block where it was defined.

However, javascript only has function scoping, where variables in one function cannot be accessed by another function. Where variables are declared in the function has no significance whatsoever, because it will still be accessible from anywhere inside that function (no block scope). Hence, both code snippets you posted are equivalence to whatever interpreter is running the code.

The second is preferable because it is clearer as it shows where the variable will be used (throughout the function). It also prevents the variable from being declared twice inside the scope of the function, which may not necessarily cause anything bad to happen, but it will definitely not cause anything beneficial. You should almost always declare a variable once at a higher level instead of twice at different lower levels, even though it doesn't really matter since the scope of the variable will be the entire function no matter where it is declared.

JavaScript does not have block scope. Variables are scoped to the function they are defined in, meaning that when you declare a variable inside of an if block, it is "hoisted" to the top of the function.

Since the variable is technically defined at the top of the function anyway, it is considered a best practice to move variable declarations to the top of the function so that the intent of the code is clear.

I'd say your code isn't "wrong" but it is misleading to people reading the code who aren't familiar with how scope works in JavaScript. I would definitely opt for the second version, because it actually reflects how the code is executed.

Here's a good article explaining variable hoisting.

Declare your var pointer once with-in the function you have your if statement at. Like ninjagecko mentioned all vars get sent to the top of their containing functions.

However; do be careful because if you declare the same var twice like you have it , it will reset the var.

I recommend doing this:

var result = MORE_LIKELY_OUTCOME;

if (LESS_LIKELY_CONDITION) {
    result = LESS_LIKELY_OUTCOME;
}

process(result);

This way, you are setting result initially to what you are expecting it to be most of the times. Then, the if statement will change result if the condition occurs.

It turns out that SublimeLinter is using JSHint which has the option to surpress this warning and explains why it exists.


funcscope This option suppresses warnings about declaring variables inside of control structures while accessing them later from the outside. Even though JavaScript has only two real scopes—global and function—such practice leads to confusion among people new to the language and hard-to-debug bugs. This is way, by default, JSHint warns about variables that are used outside of their intended scope.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM