PDA

View Full Version : how to use multiple if statements, no not else if

dazappa
12-16-2005, 09:35 PM
I want to be able to use multiple if statements like:

if (var1 = 5) AND (var2 = 5)

so I want to be able to check 2 or more things, and if both are true continue on and perform some code. (and this is different topic than last thread so please dont get mad)

liorean
12-16-2005, 09:45 PM
By using the boolean logic operators

LogicalANDexpression: expression1 && expression2

Which does the following:
1. Evaluate expression1
2. Convert the result of #1 to Boolean
3. If the result of #2 is false, return the result of #1
4. Evaluate expression2
5. Return the result of #4

LogicalORexpression: expression1 || expression2

Which does the following:
1. Evaluate expression1
2. Convert the result of #1 to Boolean
3. If the result of #2 is true, return the result of #1
4. Evaluate expression2
5. Return the result of #4

LogicalNOTexpression: ! expression

Which does the following:
1. Evaluate expression
2. Convert the result of #1 to Boolean
3. If the result of #2 is true, return false
4. Return true

PhotoJoe47
12-16-2005, 10:09 PM
Liorean,

I don't agree with your definition of the boolean operators.

A "logical and" (&&) will only return true if both expression are true. If either expression 1 or expression 2 is false the result will be false.

A "logical or" (||) will return true if either or both expressions is true.

dazappa
12-16-2005, 10:15 PM
Liorean,

I don't agree with your definition of the boolean operators.

A "logical and" (&&) will only return true if both expression are true. If either expression 1 or expression 2 is false the result will be false.

A "logical or" (||) will return true if either or both expressions is true.
so, what is the correct syntax? is it:

if (var1 = 5) || (var2 = 5)

fci
12-16-2005, 10:22 PM
did you try if (var1 = 5 || var2 = 5) alert('yay');

PhotoJoe47
12-16-2005, 10:30 PM
I want to be able to use multiple if statements like:

if (var1 = 5) AND (var2 = 5)

so I want to be able to check 2 or more things, and if both are true continue on and perform some code. (and this is different topic than last thread so please dont get mad)

if((var1 == 5) && (var2 == 5))
{
}

"var1 = 5" will set the value of var1 to 5. To test if var1 is equal to the value of 5 you have to use "==" the equality conditional test symbol

dazappa
12-16-2005, 10:39 PM
Joe yes I did know i needed == ok well anyways, I tried to implement your code into part of my script and I got syntax error. Just to let you know, I have some functions in there, SetCookie and GetCookie that i know work, and I will not post them in the following code. I am posting the troublesome part.

function use1() {
var hpup
hpup = parseInt(hp) + 5;
if ((item1 == 'Apple') && (hpup <= maxhp))
}
alert('You ate the apple and restored 5hp');
{
else
alert('You do not have a usable item');

}

Edit: WAIT look at my if statement lol i got the braces backwards >.> ok that fixed that problem >.> but look at the second part of my if statement anyways. I use <= but is there anyway that lets say my hp was 19. How would I make it so it wouldnt go to 24?

PhotoJoe47
12-16-2005, 10:47 PM
Joe yes I did know i needed == ok well anyways, I tried to implement your code into part of my script and I got syntax error. ......

What did the syntax error point to? Can you cut the error message from the javascript console and paste it into a message reply here?

dazappa
12-16-2005, 11:01 PM
What did the syntax error point to? Can you cut the error message from the javascript console and paste it into a message reply here?
The syntax error only stated a line number. I went that line number and discovered that my braces were backwards. Look carefully at my if statement and you will notice i switched them. After fixing that stupid typo the program worked. but i have a question about (&&) Could I have for example...

function use1() {
var hpup
blah = 3;
hpup = parseInt(hp) + 5;
if ((item1 == 'Apple') && (hpup <= maxhp) && (blah = 3))
}
alert('You ate the apple and restored 5hp');
{
else
alert('You do not have a usable item');

}
is it possible to have 3 comparisons like the above example?

liorean
12-16-2005, 11:02 PM
so, what is the correct syntax?
if(a && b)
c;
Liorean,

I don't agree with your definition of the boolean operators.Then see me prove by exampe that I am, in fact, right. Let's just run the following code:
var
o={
'false':false,
'true':true,
'null':null,
'{}':{}},
a=[],
i,
j;

for(i in o){
for(j in o){
a.push(i+' && '+j+': '+(o[i]&&o[j]));
a.push(i+' || '+j+': '+(o[i]||o[j]));
}
a.push('! '+i+': '+(!o[i]))
}

a.join('\n');The results will be a list of all possible boolean logic operations with the four values: false (boolean, casts to false), true (boolean, casts to true), null (object, casts to false), object literal (object, casts to true).

The list, if we look only on the && operator, will look like this:
false && false: false
false && true: false
false && null: false
false && {}: false
true && false: false
true && true: true
true && null: null
true && {}: [object Object]
null && false: null
null && true: null
null && null: null
null && {}: null
{} && false: false
{} && true: true
{} && null: null
{} && {}: [object Object]What can be read out of this? Well, first of all, the results for false as first operand all return false. To go through the list:
1. It evaluates the first expression (false).
2. false cast to boolean is false
3. #2 is false, so it returns #1 (false)

The results for null as first operand behave similarly, they all return null. To go through the list:
1. It evaluates the first expression (null)
2. null cast to boolean is false
3. #2 is false, so it returns #1 (null)

The results for true as well as the object literal as first operand we see return whatever is the value of the second operand in all cases. To go through the list:
1. It evaluates the first expression (true or obect)
2. (true or object) cast to boolean is true
3. #2 is true
4. It evaluates the second expression
5. It returns #4

The list, if we look only on the || operator, will look like this:
false || false: false
false || true: true
false || null: null
false || {}: [object Object]
true || false: true
true || true: true
true || null: true
true || {}: true
null || false: false
null || true: true
null || null: null
null || {}: [object Object]
{} || false: [object Object]
{} || true: [object Object]
{} || null: [object Object]
{} || {}: [object Object]What can be read out of this? Well, first of all, the results for true as first operand all return true. To go through the list:
1. It evaluates the first expression (true).
2. true cast to boolean is true
3. #2 is true, so it returns #1 (true)

The results for object literal as first operand behave similarly, they all return the object. To go through the list:
1. It evaluates the first expression (object)
2. object cast to boolean is true
3. #2 is true, so it returns #1 (object)

The results for false as well as null as first operand we see return whatever is the value of the second operand in all cases. To go through the list:
1. It evaluates the first expression (false or null)
2. (false or null) cast to boolean is false
3. #2 is false
4. It evaluates the second expression
5. It returns #4

PhotoJoe47
12-16-2005, 11:23 PM
The syntax error only stated a line number. I went that line number and discovered that my braces were backwards. Look carefully at my if statement and you will notice i switched them. After fixing that stupid typo the program worked. but i have a question about (&&) Could I have for example...

function use1() {
var hpup
blah = 3;
hpup = parseInt(hp) + 5;
if ((item1 == 'Apple') && (hpup <= maxhp) && (blah = 3))
}
alert('You ate the apple and restored 5hp');
{
else
alert('You do not have a usable item');

}
is it possible to have 3 comparisons like the above example?

Yes you can, you can have as many as you want.

Try this test code:

<script type="text/javascript">
var x = 0;
var y = 10;
for( i= 1; i < 7; i++)
{
x = x + 1;
y = y - 1;
if((x==5) && (y==5) && (i==5))
{
alert('x , y and i are all equal and they all equal 5')
}
else
{
alert('x = ' + x + ' y = ' + y + ' i = ' + i)
}
}
</script>

PhotoJoe47
12-16-2005, 11:42 PM
Liorean,

I can't seem to follow your logic. I sounds like double talk to me, but that could be because by brain is getting old.:)

But I stand by my defination of "logical and" and "logical or"

From what I understand javascript will check the first expression first.

With the && if the first expression is false, it stops right there and returns false. If it is true then it checks the next expression, if that expression is false it returns false, if it is true and it is the last expression it returns true.

With the || if the first expression is ture, it stops right there and returns true. If is false then it checks the next expression, if that expression is true it returns ture, if it is false and it is the last expression it will return false.

liorean
12-17-2005, 12:24 AM
Well, null && {} returns null, and the second operand will not be evaluated.

For null || {}, the second operand will be evaluted and be used as the return value.

The boolean logic operators treat their operands as if they were booleans, but they return the actual operands and not their boolean representation. They only return true or false if those were the actual operands sent to them.

Thus, to define the behavior of &&:
If first operand converted to boolean is false it returns the first operand (and not false).
Otherwise it returns the second operand.

And to define the behavior of ||:
If first operand converted to boolean is true it returns the first operand (not true).
Otherwise it returns the second operand.

Which is just what I wrote as those five steps above, but in a more plain English variant.

ralph l mayo
12-17-2005, 12:25 AM
By using the boolean logic operators

LogicalANDexpression: expression1 && expression2

Which does the following:
[...]
3. If the result of #2 is false, return the result of #1
[...]

LogicalORexpression: expression1 || expression2

Which does the following:
[...]
3. If the result of #2 is true, return the result of #1
[...]

This is true for logical AND and OR, but backwards for logical short circuit AND and OR like && and ||, where the order of parsing is left to right. The difference becomes apparent when functions are evaluated as booleans:

function returnsTrue()
{
return(true);
}

if (true || returnsTrue())
{
alert('short circuit OR triggered');
}

if (false && returnsTrue())
{
alert('short circuit AND triggered');
}

Running this code, the only alert is 'short circuit OR triggered', proving argument 2 is never evaluated.

&& : if the result of #1 is true return the result of #2, else return false
||: if the result of #1 is false return the result of #2, else return true

edit: beaten :[

Basscyst
12-17-2005, 12:26 AM
I'm gonna have to side with Joe here, while your explanation is quite lengthy, I really don't see how it proves at any point where, coming from your example of proper syntax:

if(a && b)
{
c;
}

That there is ever a time where both a and b don't return true but c is still run. Unless we both are misinterpreting what you are saying. I mean in all the JS tutorials I've read, never have I seen a 1/2 page post on the utilization of &&. ;) :p

Basscyst

Basscyst
12-17-2005, 12:30 AM
Well, null && {} returns null, and the second operand will not be evaluated.

For null || {}, the second operand will be evaluted and be used as the return value.

The boolean logic operators treat their operands as if they were booleans, but they return the actual operands and not their boolean representation. They only return true or false if those were the actual operands sent to them.

Thus, to define the behavior of &&:
If first operand converted to boolean is false it returns the first operand (and not false).
Otherwise it returns the second operand.

And to define the behavior of ||:
If first operand converted to boolean is true it returns the first operand (not true).
Otherwise it returns the second operand.

Which is just what I wrote as those five steps above, but in a more plain English variant.

Okay, I think I understand what you are saying, but I think you are splitting hairs here, seeing as the statement (if) is going to return either true or false, it doesn't seem to me that it really matters which of the statements failed within the if unless there is actually a way to detect that and perform an action from there. To the best of my knowledge there is not. for the record, I have no problem with your explanation of ||. :)

In plain english (to save the poor OP a headache if he doesn't have one already from reading this far down) I think it would be correct to say:

All statements on either side of && must return true in order for the entire statement to evaluate true.

Basscyst

ralph l mayo
12-17-2005, 12:35 AM
Okay, I think I understand what you are saying, but I think you are splitting hairs here, seeing as the statement (if) is going to return either true or false, it doesn't seem to me that it really matters which of the statements failed within the if unless there is actually a way to detect that and perform an action from there. To the best of my knowledge there is not.

Basscyst

It does matter when functions are evaluated, and it's detectable by the (absence) of function behavior. See my previous post.

liorean
12-17-2005, 12:58 AM
This is true for logical AND and OR, but backwards for logical short circuit AND and OR like && and ||, where the order of parsing is left to right.No, actually the algorithms I listed there describe just this short-circuitness of the evaluation. Let's look at them again:
LogicalANDexpression: expression1 && expression2

Which does the following:
1. Evaluate expression1
2. Convert the result of #1 to Boolean
3. If the result of #2 is false, return the result of #1In other words, evaluate first (left) operand, and if that converted to boolean is false, return it.

However, if it's not false when converted to boolean, we will continue to evaluate the second (right) expression and return that.

4. Evaluate expression2
5. Return the result of #4

I mean in all the JS tutorials I've read, never have I seen a 1/2 page post on the utilization of &&. Hehe. Look at the ECMA262-3 spec, then:
11.11 Binary Logical Operators
Syntax
LogicalANDExpression :
BitwiseORExpression
LogicalANDExpression && BitwiseORExpression

LogicalANDExpressionNoIn :
BitwiseORExpressionNoIn
LogicalANDExpressionNoIn && BitwiseORExpressionNoIn

LogicalORExpression :
LogicalANDExpression
LogicalORExpression || LogicalANDExpression

LogicalORExpressionNoIn :
LogicalANDExpressionNoIn
LogicalORExpressionNoIn || LogicalANDExpressionNoIn

Semantics
The production LogicalANDExpression : LogicalANDExpression && BitwiseORExpression is evaluated as follows:
1. Evaluate LogicalANDExpression.
2. Call GetValue(Result(1)).
3. Call ToBoolean(Result(2)).
4. If Result(3) is false, return Result(2).
5. Evaluate BitwiseORExpression.
6. Call GetValue(Result(5)).
7. Return Result(6).

The production LogicalORExpression : LogicalORExpression || LogicalANDExpression is evaluated as follows:
1. Evaluate LogicalORExpression.
2. Call GetValue(Result(1)).
3. Call ToBoolean(Result(2)).
4. If Result(3) is true, return Result(2).
5. Evaluate LogicalANDExpression.
6. Call GetValue(Result(5)).
7. Return Result(6).

The LogicalANDExpressionNoIn and LogicalORExpressionNoIn productions are evaluated in the same manner as
the LogicalANDExpression and LogicalORExpression productions except that the contained
LogicalANDExpressionNoIn, BitwiseORExpressionNoIn and LogicalORExpressionNoIn are evaluated instead of the
contained LogicalANDExpression, BitwiseORExpression and LogicalORExpression, respectively.

NOTE The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the
value of one of the two operand expressions.

My description is pretty close to the real deal, I think :)
And haven't you learnt to never get into an argument with me about JavaScript semantics yet?

Basscyst
12-17-2005, 01:25 AM
And haven't you learnt to never get into an argument with me about JavaScript semantics yet?

Heh, I did do so tentativley. I really only did it because your 2nd example was convoluded and hard to follow (for me anyway), so I really had no idea what you were saying. Just wanted to make sure you did. :p I suppose it does matter the order in which they are evaluated, now that I think about it. Often when traversing the DOM I'll check if a node is a tag like:

if(element.tagName && element.className=="something")
{
do this
}

If both were evaluated regardless I would get an error on the second if the tagName did not exist.

ralph l mayo
12-17-2005, 01:39 AM
Originally Posted by liorean
LogicalANDexpression: expression1 && expression2

Which does the following:
1. Evaluate expression1
2. Convert the result of #1 to Boolean
3. If the result of #2 is false, return the result of #1

[dumb]
It's still backwards I think. To demonstrate short circuit behaviour it seems this should be:

1. Evaluate expression1
2. Convert the result of #1 to Boolean
3. If the result of #1 is true, return the result of #2

Using your method, the code I posted earlier would show the alert from returnTrue() at step 3 trying to get its value to determine whether to return the result of #1.
[/dumb: see edit 2]

Alternatively,
1. Evaluate expression1
2. Convert the result of #1 to Boolean, return it if it's false
3. If the result of #2 is false, return the result of #1

Maybe you meant to imply the short circuit was in step 2, but if it's to be read as only returning on line 3 your model (and apparently the spec) doesn't match the behavior.

edit: missed this:

In other words, evaluate first (left) operand, and if that converted to boolean is false, return it.

So that's where the confusion was. We're in agreement.

edit 2: also I am an idiot and I was thinking #1 and #2 referred to expression1 and expression 2, respectively, and not the preceeding line numbers. Reading is fundamental :(

liorean
12-17-2005, 01:50 AM
It's still backwards I think. To demonstrate short circuit behaviour it seems this should be:

1. Evaluate expression1
2. Convert the result of #1 to Boolean
3. If the result of #1 is true, return the result of #2

Using your method, the code I posted earlier would show the alert from returnTrue() at step 3 trying to get its value to determine whether to return the result of #1.No no no. #1 is the evaluated expression1. #2 is #1 converted to boolean. expression2 doesn't enter my algorithm until at #4, which will only be reached if #3 didn't return a value.

And apparently you edited your post two times before I was finished with this post :)

PhotoJoe47
12-17-2005, 05:49 AM
So Liorean,

Does this mean that javascript && and || are not a real(true) boolean operators? But that they are as close as javascript can get? Also are you saying that some expression just can not be evaluated to either true or false?

liorean
12-17-2005, 07:27 AM
They are not "true" boolean if you mean by that that they can only return boolean values, no. They are, like most boolean processing in JavaScript, done on any type of value, autocasting to boolean, comparison is done with the cast value, but return is the original value corresponding to the boolean it used for the comparison.

This is for the purpose of chaining stuff, and is similar to a lot of other languages that base their syntax mainly on C/C++.

If you want to handle only booleans, use strict comparisons, the Boolean native, unary logical NOT (!) or similar.

Pyth007
12-19-2005, 01:44 PM
liorean's example also shows why using the assignment operator will work as well as utilizing it as a boolean:

var nextRow;
var myArray = ["1","2","3"];
while(nextRow=myArray.pop() && nextRow!="junk")
{
// Do stuff here
}
alert("nextRow has type of: "+typeof nextRow);

According to this code, the pop() function will return "undefined" for the last iteration, convert that "undefined" to false, and return "undefined". If you wanted to use the first value of the array outside of the loop (the last true value that pop() returned), you couldn't use nextRow since that had been evaluated according to liorean's step #1 to set nextRow to "undefined" type.

felgall
12-19-2005, 08:09 PM
With A && B the second expression (B) is only evaluated if the first expression (A) is true. If the first expression is false then the && B is ignored. This allows you to use code like (for example):

if (document.getElementById && document.getElementById('myid'))

If the browser doesn't recognise the getElementById method then it won't try to run it. If you omitted the first part or put the tests the other way around then browswers that don't understand getElementById would crash with method/function not found when trying to run it for 'myid'.

Similarly with A || B the second expression is not evaluated if the first is true.

Javascript only evaluates as many tests as it needs to to get a definitive result.

Pyth007
12-20-2005, 02:58 PM
I think people are starting to re-hash old ground... The problem with understanding liorean's original algorithm is that when it says stuff like "if the result of #2 is false", he is talking about step #2 in the algorithm, not expression2! The algorithm just shows that a literal boolean type (eg 'true' or 'false') isn't necessiarily returned; if expression1 evaluates to 'false', the item that is actually returned may be of type "null" or "undefined" instead of "boolean"...