In ES6, I can achieve block scoping per case:
switch(somVar){
case 'first':
{
let itemId='foo';
}
break;
case 'second':
{
let itemId='bar';
}
}
Obviously, itemId
might as well be declared on top.
For my use case, locally scoped variables make more sense because in my overall code, it is more easily identifiable what's happening, and there are a number of case
's, whereas some blocks contain the variable in question and others don't.
I have't seen block scoping used for switch/case
as mon usage.
My question is simply, whether there are reasons not to do it, stylistic-wise or else.
Edit, updated example code to avoid confusion:
const someFunc(action) => {
switch(action.type){
case 'first':
{
let itemId=action.someObj.someProp.id;
//Do something with itemId
}
break;
case 'second':
{
let itemId=action.someObj.someProp.id;
//Do something with itemId
}
break;
case 'third':
//No use of itemId
}
}
itemId could be declared at the top, but I'd prefer to look at the property per case. There doesn't appear to be an immediate reason to share the variable across different cases. It would also appear to be nonsense to 'invent' a different name for what is essentially the same.
This could probably be written differently, but this example is a mon pattern in Flux architecture.
In ES6, I can achieve block scoping per case:
switch(somVar){
case 'first':
{
let itemId='foo';
}
break;
case 'second':
{
let itemId='bar';
}
}
Obviously, itemId
might as well be declared on top.
For my use case, locally scoped variables make more sense because in my overall code, it is more easily identifiable what's happening, and there are a number of case
's, whereas some blocks contain the variable in question and others don't.
I have't seen block scoping used for switch/case
as mon usage.
My question is simply, whether there are reasons not to do it, stylistic-wise or else.
Edit, updated example code to avoid confusion:
const someFunc(action) => {
switch(action.type){
case 'first':
{
let itemId=action.someObj.someProp.id;
//Do something with itemId
}
break;
case 'second':
{
let itemId=action.someObj.someProp.id;
//Do something with itemId
}
break;
case 'third':
//No use of itemId
}
}
itemId could be declared at the top, but I'd prefer to look at the property per case. There doesn't appear to be an immediate reason to share the variable across different cases. It would also appear to be nonsense to 'invent' a different name for what is essentially the same.
This could probably be written differently, but this example is a mon pattern in Flux architecture.
Share Improve this question edited Aug 8, 2016 at 13:32 Trace asked Aug 8, 2016 at 12:10 TraceTrace 18.9k21 gold badges96 silver badges171 bronze badges 11-
Most of the times, a variable is created before
switch
and returned/used afterswitch
depending on the case. – Tushar Commented Aug 8, 2016 at 12:14 -
5
I don't see any reason not to do this. This is the whole point of block-level scoping. You just need to make sure you create blocks for your
case
s, otherwise you might try to define the same variable twice in theswitch block
, causing a syntax error. – Ozan Commented Aug 8, 2016 at 12:17 - 3 I'd say there are two large reasons for it not being mon usage: 1) you couldn't do it pre-ES6; 2) situations where it's useful don't e up too often. There's no reason why you shouldn't do it. – Etheryte Commented Aug 8, 2016 at 12:17
- @Tushar I agree. However in my use case, I have a variety of cases that sometimes perform action on variables that are similar (hence would have the same name), but often also on entirely different variables. It is within the scope of action creators / reducers with Flux/Redux. It appears to make more sense to 'encapsulate' local variables without needing to care for the outside scope. – Trace Commented Aug 8, 2016 at 12:17
- 1 @Sukima When an object is passed to the function that handles the switch statement, there can be nested attributes that are more easy to work with when storing in a local variable, rather than to write the entire 'path'. I would prefer to use 'let' per case to explicitly declare. There is no certaint which case uses which attributes of the object passed in. Perhaps this is clearer. If there is pelling reason not to, I of course like to hear. – Trace Commented Aug 8, 2016 at 12:29
2 Answers
Reset to default 2Abstract the logic into functions. Switch statements by themselves are difficult to read let alone a bunch of logic and variable scoping. It is much better to abstract the logic into functions. Also after abstracting to functions you will probably notice that there isn't much need for a switch statement all together. See Avoid use of switch statements section of the DockYard style guides.
function handleFirstCase() {
var itemId = 'foo';
// Do stuff with itemId
return expectedValue;
}
function handleSecondCase() {
var itemId = 'bar';
// Do stuff with itemId
return expectedValue;
}
let result;
switch(somVar){
case 'first':
result = handleFirstCase();
break;
case 'second':
result = handleSecondCase();
break;
}
Notice how the switch statement bees one line. This can easily be distilled to a dictionary lookup instead:
const CASES = {
first() {
var itemId = 'foo';
// Do stuff with itemId
return expectedValue;
},
second() {
var itemId = 'bar';
// Do stuff with itemId
return expectedValue;
}
};
let result = CASES[someVar]();
The problem occures due to switch scenario is handled as a single block, irrespective of the individual case statments, as the 'break' statement is optional.
Rewriting your code to the following should do the job:
const someFunc(action) => {
if (action.type == 'first'){
let itemId=action.someObj.someProp.id;
//Do something with itemId
}
else if (action.type == 'second'){
let itemId=action.someObj.someProp.id;
//Do something with itemId
}
else { //Third
//No use of itemId
}
}