I ran across an interesting problem today (Firefox 44). I have a conditional statement that is evaluating the else if statement after evaluating a 'true' if statement. Take an example:
The initial state of .dataRow is collapsed. When a dataRow is clicked the first condition is found to be true and the class is changed to expanded. Next the else if statement is evaluated and the class is changed back to collapsed because it changed to expanded in the previous condition! Why in the world would the else if statement be evaluated after the first condition is found true?
$("div").on("click", "div.dataRow", function(){
if ($(this).hasClass("collapsed"))
{
$(this).removeClass("collapsed").addClass("expanded");
}
else if($(this).hasClass("expanded"))
{
$(this).removeClass("expanded").addClass("collapsed");
}
});
I had to put return statements in the conditions to get the function to work properly.
$("div").on("click", "div.dataRow", function(){
if ($(this).hasClass("collapsed"))
{
$(this).removeClass("collapsed").addClass("expanded");
return false;
}
else if($(this).hasClass("expanded"))
{
$(this).removeClass("expanded").addClass("collapsed");
return false;
}
});
EDIT
Here is a simplified reproduction of the problem jsFiddle
I am not into removeClass and addClass of jQuery right now. But each "else if" block condition is evaluated. As you add the class in the first block, the second condition is always true after that.
If you have only two conditions, I would advise you to only use "else". That would protect the second block from being executed, if the first was executed.
Related
I'm interested at what point of time a condition in an if/else statement gets evaluated.
Imagine there's the following sample:
if (complex condition 1) {
do something
}
else if (complex condition 2) {
do something else
}
else if (complex condition 3) {
do something else
}
else {
do anything
}
What I want to know is: does each of the complex conditions get check on ahead of time, and the interpreter just execudes the codepart of the condition that is true, or does it start with the first condition when it comes to it and only evaluates the second condition when the first one is false?
I'm interested in regards to make some optimizations for low-end mobile devices.
The condition clause of an if statement is evaluated when the if statement is reached in the flow of execution. In your example, if the first condition is true, then none of the other conditions will be evaluated.
As "Short-circuit_evaluation" says: "...the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression."
The execution will stop when reach a true statement.
I ran into this piece of code:
<a ng-click= "item.statusId !== itemStatus.in || transfer()">
I guess we can generalize as:
<element ng-click = "someVar !== someValue || doStuff()">
I then found this article on short circuits and another more focused one once I knew what they are called. However, I still don't get it.
Does it basically work on the principle of an OR statement ending evaluation if the first statement evaluates to true? So if the first statement is true, end evaluation, if it's false, run the function in the second half of the OR statement? (This is the main question I am asking, everything else is extra).
I guess that part I don't get is whether the compiler interprets this code differently or it still evaluates to false and just runs the function. Not even sure how to phrase Q.
Does it basically work on the principle of an OR statement ending evaluation if the first statement evaluates to true? So if the first statement is true, end evaluation, if it's false, run the function in the second half of the OR statement?
It's effectively shorthand for an if statement, and you intuited correctly why it works. For more details on short-circuit evaluation in JavaScript, see this Stack Overflow question.
That code is equivalent to:
//Note the intentional and explicit use of `== false` to mean falsy (NOT `=== false` to indicate strict equality test for false)
if( (item.statusId !== itemStatus.in) == false ) {
transfer();
}
It is an interesting means of executing a function only when a condition is falsy.
There are many different examples of this around on StackOverflow, and is not specific to AngularJS.
Can anyone tell me why in the following code a do/while lop is used rather than a simple if statement:
function prev(elem){
do {
elem = elem.previousSibling;
} while(elem && elem.nodeType != 1);
return elem;
}
Why not:
function prev(elem){
if(elem && elem.nodeType != 1) {
elem = elem.previousSibling;
return elem;
}
Is there an advantage to using do/while? Thanks!
do-while will run once and continue running while the statement is true, while the if-statement will only run once.
In this instance it may be equivalent (depending on how the code and data is set up), but typically that is how do-whiles are used.
If you want something to keep repeating until a certain condition is met, use the do,for, or while statement. If you only want to check something once, use the if statement.
If you are using do while loop, then your statements will execute atleast once. Then a condition is checked and if the condition is not satisfied then the statement are not executed any more. But if you use the other option then first condition is checked and if the condition is satisfied then the statements are executed only once. Otherwise they are not executed even a single time.
A While or Do While statement is a continuous loop until a condition is met.
An If, Then, Else/Else If is a simple evaluative statement rather than a loop.
Here do-while will run atleast once, and will execute until while condition is met.
But in the if-statement, it'll check the condition first, and will execute once only and will return the response.
I have the following switch statement in JavaScript :
switch(scrollable.direction){
case "top" :
break;
case "left" :
break;
case "right" :
scrollable.select("."+lineCssClass).invoke("setStyle", {float: "right"});
break;
case "bottom" :
alert("Bottom scrolling not implemented yet ! Sorry !");
return;
}
(the "invoke" bit is prototype.js, but it's no relevant to the question anyway)
It is inside a function. I want that if the value is "bottom" a message is displayed and the method execution stops.
The problem is that if the value is e.g. "top", the break is executed, but the execution jumps to the return; statement instead of exiting the switch statement.
I actually solved the problem by adding an additionnal break; after the return, which is actually dead code since it can never be executed.
But I would be curious to know why it executed the "return" in the first place ?
Edit: I am sorry, the "return" wasn't actually executed. I was stepping through the code using Firebug and it actually stepped on and highlighted the "return" line, but it wasn't executed.
There are other problems in my code that cause it not to work as expected, and I was wrongly blaming this.
My bet is that your scrollable.direction is giving you a worng value that is not a real direction.
Add a default clause to your switch statement (as you should always do, btw) to check it out
switch(scrollable.direction){
/*...*/
case "bottom" :
alert("Bottom scrolling not implemented yet ! Sorry !");
return;
default:
console.log(scrollable.direction, 'is not a direction');
break;
}
As I said in the edit I made to the question, the problem was actually not that the return; was executed, but that Firebug gave the impression it was when I went step by step through the switch statement.
Alsot, after some more tests, I can reproduce this weird thing only when I enclose the switch/case statement in a try block.
As missingno suggested I will leave this question in case other people are confused by this behaviour of Firebug.
Similar sort of issue occurred with me while using Firebug but on the IF statement.
if(multiship == true)
{
// do something
}
else
{
// do something
}
The debugger showed that the script execution took the if path instead of having multiship variable equal to false.
I'm new to javascript and am having issues with a seemingly simple if/else statement.
Can anyone let me know why the below isn't working please (Im pulling my hair out)
var is_expanded = false;
if (is_expanded==false) {
alert('no');
is_expanded = true;
} else {
alert('yes');
}
I always get the 'no' alert (I never get to the else part).
Cheers for any help.
This is working as designed.
The condition is checked when you say if. It then goes into the correct block, in this case the one that alerts "no".
The condition does not get re-evaluated after the block has been executed. That's just not how the if statement works, not in any language I know.
Depending on what you want to do, there are other patterns and constructs that can help you, for example a while loop. Maybe show the real use case that you need this for.
That's because is_expanded always equals false because you've set it as false BEFORE the if statement.
else will not fire unless is_expanded equals true before the if statement.
You previous line of code says var is_expanded = false;
which means if (is_expanded==false) will always evaluate to true.
So that is exactly what you are getting as output. What did you expect?
Next time when your same method is called, the value for is_expanded is again reset to false due to your first line of code. Then again it will alert no
That's normal. You have set the variable is_expanded to false so in the if statement you are always entering the alert('no'); part. After you set the variable to true but there is no longer any if statement executed.
var is_expanded = false;
if (is_expanded==false) {
alert('no');
is_expanded = true;
} else {
alert('yes');
}
Congratulations! Your code is working perfectly, so stop pulling your hair out.
The nature of IF/ELSE is that only one of them fires per pass. So, your code checks whether is_expanded is FALSE. If it's false, it will run the IF part. If not, it'll run the ELSE part.
Just read it like english.
If something, do this. Otherwise, do something else
Even if you change the value of the variable inside one of the blocks, it won't matter because once it checks the block, it moves on.