Why is "else" necessary?

Tell us what’s happening:

In searching for an answer to this, it seems like some people have already asked, “why not just replace an “else” statement with another “if” statement?” To be clear, that is not my question.

In the lesson “Basic JavaScript: Introducing Else Statements,” we are told that the way to get some code to run if the “If” condition is false, is to use an “else” statement. Their example:

if (num > 10) {
  return "Bigger than 10";
} else {
  return "10 or Less";
}

BUT, in the earlier lesson “Basic JavaScript: Use Conditional Logic with If Statements,” the following example is used:

function test (myCondition) {
  if (myCondition) {
     return "It was true";
  }
  return "It was false";
}

The part I put in bold seems like it is equivalent to an “else” statement. As the lesson goes on to describe: " When test is called with a value of true , the if statement evaluates myCondition to see if it is true or not. Since it is true , the function returns "It was true" . When we call test with a value of false , myCondition is not true and the statement in the curly braces is not executed and the function returns "It was false" ." So the code \return “It was false”\ executes when the condition is false… just like if you used an else statement, right?

So I guess my specific questions is, couldn’t we just drop the else statement in the initial example, and have simply:

if (num > 10) {
  return "Bigger than 10";
} 
  return "10 or Less";

Would that accomplish the same thing? If so, then what is the point of the “else” statement?

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36.

Challenge: Use Conditional Logic with If Statements

Link to the challenge:
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/use-conditional-logic-with-if-statements

Maybe this is just an ambiguity caused by really simple examples, and “else” has other uses that wouldn’t be so easily done away with?

The two functions

function test1 (myCondition) {
  if (myCondition) {
    return "It was true";
  } else {
    return "It was false";
  }
}

and

function test2 (myCondition) {
  if (myCondition) {
     return "It was true";
  }
  return "It was false";
}

will do the same thing. Personally I find the first to be more human readable. It all comes down to a question of style.

Now, when you get to more complex examples, this is not the case.

function testA (myCondition) {
  if (myCondition) {
    print("Do Thing A\n");
  } else {
    print("Do thing B\n");
  }
  return 0;
}

and

function testB (myCondition) {
  if (myCondition) {
    print("Do thing A\n");
  }
  print("Do thing B\n");
  return 0;
}

are very different. Do you see why? What happens if your condition is true in testA vs testB?

1 Like

The reason that the else isn’t necessary in that example is because both the if and the else blocks include a return. As soon as a return is executed, the function is done. When the if condition is satisfied, the function returns the expected result. If the condition was not satisfied, then either the else or the next command is executed.

if (num > 10) {
    return "Greater than 10";
} else {
    return "Less than 10";
}
// gives the same result as
if (num > 10) {
    return "Greater than 10";
}
return "Less than 10";

//// but ////
if (num > 10) {
    moreOrLess = "Greater";
} else {
    moreOrLess = "Less";
}
return moreOrLess + " than 10";
// does NOT give the same result as
if (num > 10) {
    moreOrLess = "Greater";
}
moreOrLess = "Less";
return moreOrLess + " than 10";
3 Likes

I think those examples really help. Thank you! To answer your question, and see if I actually understand, is this correct?:

If the condition is true in testA, then only the first print statement would run, while if the condition were true in testB, both print statements would run, because the second print statement is not logically connected to the if statement. So it seems that things start to get different when the code isn’t just return statements.

1 Like

Thank you ArielLeslie! That’s a really helpful reminder that once any return is executed, a function is done. That definitely rings some bells, and helps clarify what I was not seeing. Thanks for taking the time.

1 Like

You’ve got it! return is a special case.

This is correct syntax also:

if (true)
  console.log(' stement executed ')
else 
  console.log('something else')

It may get confusing when you combine this style with block style { }.

No one else really pointed this out about how if-else works:

if (exp) {
    // statement 1
} else {
    // statement 2
}
// statement 3
  • Statement 1 will run ONLY if the “if” expression evaluates to true.
  • Statement 2 will run ONLY if the “if” expression evaluates to false.
  • Statement 3 will run regardless whether the “if” expression evaluates to true OR false.

So you don’t always want to omit the “else” clause, it really depends on what you want to happen.

1 Like

This is only true if the statements in the if and else code blocks are not return statements.

2 Likes

As Randy says, it doesn’t matter in this case because of the return statements.

Personally I prefer the second one. At work there are people that adamantly insist on the first and some that insist the second is better. And a lot of people who don’t mind either. Personally I like the second because it is less busy, there is less visual noise. The down sides? The two “sibling” return statements aren’t at the same indentation level which you could argue makes it marginally harder to visually parse. There is also the problem that if the if block gets to big, you may not realize what is going on. But then, I try not to let my if blocks to big. Typically when I use the second format, it is just a few lines - if I need more than that I put it in a function.

But again, it’s a matter of preference.

My preference is (generally) to reduce the number of return statements.

1 Like

In my opinion if you put else you potentially writing too imperative, I always triple check before I use one and generally, it’s a pretty rare case.

For example, test function from above not only looks leaner but actually performs better if written like so:

function test (myCondition) {
  return myCondition ? "It was true" : "It was false";
}

For me, clarity is king. I know who will debug this code. “Well of course I know him. He’s me.”

I want debugging and refactoring to be as easy and painless as possible, so I avoid stripping characters ‘to reduce visual clutter’ in favor slightly more verbose but clearer syntax. I’m careful and sparing in my use of ternaries.

But I spend a lot of effort in performance refactoring, so it makes good sense for me to prioritize code clarity. Everyone has their personal preferences. So long as the code is correct and others can debug it, its fine.

So in the case of the early return pattern, as we’ve heard, both are valid - either simply return inside the if statement, and if you haven’t, you’re logically in the else part.

However, you won’t always want to return early. Suppose you’re building a string, and that string is based on a few different alternatives in a few different places. You won’t want to return early, as that would leave the function before the various alternatives have been parsed. Instead, you’d likely need some sort of else statement (or a switch/case, which is an elaborate if/else IMO).

Point is, if you are doing some processing within your function and you will need to process multiple parts, the early return model can break things.

function buildAComplexString(name, gender, pet){
  let returnedString = "Hello, ";
  if(name !== ""){
    returnedString += name+"! ";
  } else {
    returnedString += "you! ";
  }
  returnedString += "So you are a ";
  if(gender.toLowerCase() == "m"){
    returnedString += "man";
  else if(gender.toLowerCase() == "f"){
     returnedString += "woman";
  } else {
    returnedString += "person";
  }
  if(pet && pet !== ""){
    returnedString += " with a "+pet;
  }
  returnedString += ".";

  return returnedString;
}

That one built a string from a series of silly if/else, then finally returned the result. The option, if we wanted to hide those if/else statements, would be to put them in function calls, and have those do the early return thing, returning to the main function their result. The main function, then, has no if/else calls.

function buildAComplexString(name, gender, pet){
  // We still have an if, we simply hide it away.
  function getName(name){
    if(name && name !== "") {
      return name;
    }
    return "you";
  }
  
  function getGender(gender){
    if(gender.toLowerCase() === "m"){
      return "male";
    } else if(gender.toLowerCase() === "f"){
      return "female";
    }
    return "person";
  }

  // Later, you'll learn about *ternary operators*, which are an if/else shorthand. The
  //  following line does the same as the ones above - if pet is defined and not a "",
  //  then return the type of pet string. Otherwise, just a period.
  const getPet = (pet) => (pet && pet !== "") ? " You have a "+pet+"."; : " You don't have a pet.";

  // We are still building the string from a series of if statements, but we have 
  //  abstracted them. Each function above handles a single purpose, getting a name
  //  or a gender or a pet option, but our main function just builds the string. 
  return "Hello, "+getName(name)+"! You are a "+getGender(gender)+getPet(pet);
   
}

This is a pretty deep (and silly) post, but the point is: returning early from a function will end that function’s execution entirely. In the event there are subsequent if/else statements, they will never run. So yeah, there is a purpose to if/else - you don’t always want to return early.

Yea, this is definitely a “personal style” thing. I’m a verbal gerbil so what’s “visual clutter” to somebody else is “clarifying language” to me. I do want to get to where I can just “read” a ternary if then else statement, though, and I"m almost there :wink:

2 Likes

I guess I would agree that in the specific example given, I would have written it with a simple ternary. I was speaking more generally about returning in if/else patterns.

1 Like
1) function a(b){
	
	if(typeof b==='string'){ 
		console.log(" data type is string")
	
	}
	
	if(b.length===20){
		
		console.log( b.length)
		}
	
	else{
		console.log("test case is failed")
		}
	
	}
	a("master in JavaScript")
	
	// result
	// string
	// 20
2)	function m(b){
	
	if(typeof b==='string'){ 
		console.log(" data type is string")
	
	}
	
	else if(b.length===20){
		
		console.log( b.length)
		}
	
	else{
		console.log("test case is failed")
		}
	
	}
	m("master in JavaScript")
//Result
// String
	
	

Experiment yourself

Guys… I think we may have got the question. I think we answered it. “It’s dead Jim!”. This horse has been beat. I think the quest has been fulfilled. lol

3 Likes