Why '=' and '||' will be evaluated to be true? - javascript

I read this post, it mentioned this if (variable == 1 || 2 || 6) cannot work (JS Short for if (a == b || a == c)).
But I tried this example, it will be evalauted to be true, why?
var a = 'apple';
if('apple2' == a || 'banana' ) {
alert('hi');
}
Here is the working example:
https://jsfiddle.net/Loun1ggj/
Update:
if('apple2' == a || 'banana' ) is not evaluated into if('apple2 == a' || 'apple' == 'banana')?

Let's break down the expression:
if('apple2' == a || 'banana' )
The first part to be evaluated is the ==, because it has highest operator precedence:
'apple2' == a
This is a standard equality, and returns false, giving us:
if(false || 'banana')
The || operator in JS returns not true or false, but whichever of its arguments is "truthy". A non-empty string like 'banana' is considered "truthy", so we end up with this:
if('banana')
Now we again look at the "truthiness" of 'banana', and the if statement proceeds.

Since 'banana' is always true, it would always run, see the below example
var a = 'apple';
if('apple2' == a) {
alert('hi');
}
if('banana'){
alert('hello');
}

if('apple2' == a || 'banana' ) is evaluated this way:
if(('apple2' == a) || ('banana') ), which is:
if :
'apple2' == a // false
||(or)
'banana' // true, since Boolean('banana') is true (a non-empty string is a truthy value)
so => if (false or 'banana') => if ('banana') // => true
It's not evaluated as if('apple2' == a || 'apple2' == 'banana' ).

According to this, the operator == has higher precedence over operator ||. So the expression is evaluated as follows:
if('apple2' == a || 'banana' )
'apple2' == a //false
'banana' //true (non-empty string)
So final evaluation will be, always true:
if(false || true) //true

There's 2 expressions here
'apple2' == a which resolve to falsy
'banana' which resolve to thruthy
Because 'banana' is not undefined or null essentially.

Related

why checking equality between three strings not works but between three numbers does?

I have checked equality between three numbers in javascript and it works. like:
1 == 1 == 1 //true
2 == 3 == 4 //false
2 == 3 == 3 //false
But when I try this check between three strings, it does not work:
'some string' == 'some string' == 'some string' //false
'a' == 'a' == 'a' //false
Does anyone know why this happens?
Thanks in advance.
Because
'some string' == 'some string' == 'some string'
evaluates the == operators in left-to-right order. It's equivalent to
('some string' == 'some string') == 'some string'
which is
true == 'some string'
which is false, because when a boolean is compared against something else, according to the spec:
If Type(x) is Boolean, return the result of the comparison ! ToNumber(x) == y.
When the right-hand side is a string, this resolves to
1 == 'some string'
which then runs
If Type(x) is Number and Type(y) is String, return the result of the comparison x == ! ToNumber(y).
but ToNumber('some string') is NaN
console.log(Number('some string'));
so the comparison evaluates to false.
On the other hand, with 1 == 1 == 1, following the same process:
1 == 1 == 1
(1 == 1) == 1
true == 1
// Rule 8, turn left side into a number:
1 == 1
true
Conclusion: Always use ===. If you use ==, you will encounter strange behavior.
1 == 1 == 1 can be interpreted as (1 == 1 (true) == 1) which is true.
But 'a' == 'a' == 'a' would be interpreted as ('a' == 'a' (true) == 'a') which would be false. as true is not equal to 'a'.

Why ternary expression is executed after falsy value in Javascript?

As far as I know expressions are not executed after falsy values in Javascript. For example in the following statement:
const result = undefined && 5;
console.log(result);
result will be undefined.
However:
const result = false && false ? 'T' : 'F';
console.log(result);
result will be equal to F. Why is the ternary expression still executed?
This is because of operator precedence: && has higher precedence (6) than ? : (4), so
false && false ? 'T' : 'F'
evaluates to
(false && false) ? 'T' : 'F'
So, the left-hand side evaluates to false first (taking the first false), and then goes on to the conditional operator.
If you had put parentheses after the &&, result would be false, as you're expecting:
const result = false && (false ? 'T' : 'F');
console.log(result);
const result = false && false ? 'T' : 'F'
As we know ternary expression is a short form of IF else condition,the above statement is like
if(false && false){
return 'T'
}else{
return 'F'
}
So result value we getting as "F"

Why my condition is always true

I would like to know in this example why my condition is always true ? Thanks
function bla() {
var qix = 'z'
if (qix === 'a' || 'b' || 'c') {
console.log('condition ok!! whats wrong???')
}
}
The problem with your code is that the if expression always evaluates to true.
qix === 'a' || 'b' || 'c'
will actually become this:
false || 'b' || 'c'
as qix is set to z. Due to loose typing, JavaScript returns true for the second expression because 'b' is a truthy value. To correct that, you need to change the expression as follows:
qix === 'a' || qix === 'b' || qix === 'c'
so that it correctly means what you're expecting.
Description of expr1 || expr2 from MDN:
Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true.
o1 = true || true // t || t returns true
o2 = false || true // f || t returns true
o3 = true || false // t || f returns true
o4 = false || (3 == 4) // f || f returns false
o5 = 'Cat' || 'Dog' // t || t returns "Cat"
o6 = false || 'Cat' // f || t returns "Cat"
o7 = 'Cat' || false // t || f returns "Cat"
o8 = '' || false // f || f returns false
o9 = false || '' // f || f returns ""
So this expression from your code, assuming qix is not 'a':
qix === 'a' || 'b' || 'c'
The first term qux === 'a' is false, which of course evaluates to false. This causes it to go to the next term which is 'b'. Non-empty strings evaluate to true, so it stops there and just becomes 'b'. Now your if statement can be thought of as just:
if ('b')
Again, 'b' evaluates to true. So your conditional is effectively doing nothing.
I think you are missing two concepts.
First how the || operator works and second coercion of javascript values.
In your code:
if ('z' === 'a' || 'b' || 'c') { ----}
Will always evaluate to true.
The reason for this is that the || operator will give back the first value which coerces to true without actually coercing the value. The associativity (order which the operators are executed) is left-to-right. This means that the following happens:
First the following will be evaluated because it has higher precedence:
'z' === 'a' // false
then we have the following expression which will be evaluated left to right:
false || 'b' || 'c'
let foo = false || 'b'
console.log(foo)
Then we have the following expression:
let foo = 'b' || 'c'
console.log(foo)
So the whole expression evulates to the string 'b'
After the expression inside the if statement is evaluated to the value 'b' this in turn then gets coerced into a boolean. Every string gets converted to true and that's why the value is always true.
This is because you 'if condition' is take 3 possible option
First say qix === 'a', this is false but you asking about 'b','c' and this option are values true because you are not compare var qix with 'b' or 'c', you only asking to IF condition, that if 'b' or 'c' are value
the operator || it is used so
if(First Condition || Second Condition || third condition){
if at least one of these options is true, then enter here
}
In ECMAScript 2016 incorporates an includes() method for arrays that specifically solves the answer
if (['b', 'c', 'a'].includes(qix)) {
this is false
}
if (['z', 'c', 'a'].includes(qix)) {
this is true
}
Or you can write so
function bla() {
var qix = 'z'
if (qix === 'a' || qix === 'b' || qix === 'c') {
console.log('condition ok!! whats wrong???')
}
}
As we know || (OR Logical Operators) returns true if either operand is true. In your if condition qix === 'a' || 'b' || 'c' in their second and third operand is string and Strings are considered false if and only if they are empty otherwise true. For this reason, your condition is always true.
Need to check qix like qix ==='b'
var qix = 'z'
if (qix === 'a' || qix === 'b' || qix ==='c') {
console.log('condition ok!! whats wrong???')
}
else{
console.log('else')
}
You could use Regex: qix.match(/^(a|b|c)$/)
Should return if qix is equals to a or b or c
var qix = 'z';
if (qix.match(/^(a|b|c)$/)) {
console.log('condition ok!! whats wrong???');
} else {
console.log('else');
}
JavaScript returns true for the second or expression because 'b' is always true.
You need to check each value against qix like so:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
var qix = 'z'
if (qix === 'a' || qix === 'b' || qix === 'c') {
console.log('condition ok!! whats wrong???')
}

If condition resolving as true when value is zero

My code basically looks like this:
console.log(placeCost) //this returns 0 (the number, not string)
if (!placeCost || placeCost == false || placeCost == "undefined" || placeCost == '') {
console.log("no")
}
else {console.log('yes')}
Results is "no" in the console. Why does this resolve as "true"?
Try using the === operator and don't check for !var if you plan to accept falsy parameters.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
if (placeCost === false || placeCost === "undefined" || placeCost === '') {
console.log("no")
} else {
console.log('yes')
}
You can refer to comparison operators :
Equality (==)
The equality operator == converts the operands if they are not of the
same type, then applies strict comparison.
So !placeCost (like its more verbose form : placeCost == false) is evaluated to true if placeCost is the 0 number as 0 is converted to the false value.
You want do a strict comparison ?
Use === that performs no conversion :
The identity operator returns true if the operands are strictly equal
(see above) with no type conversion.
if placeCost is 0
then !placeCost become 1, that will leads the condition is true.
if (!placeCost) // condition true when placeCost is 0

How can I break the law of non-contradiction in Javascript?

The law of non-contradiction dictates that two contradictory statements cannot both be true at the same time. That means that the expressions
(a && !a)
(a == !a)
(a === !a)
should always evaluate to a falsy value, and
(a || !a)
should always evaluate to a truthy value.
Fortunately, though, Javascript is a fun language that allows you to do all sorts of sick things. I bet someone a small fortune that it's possible to convince Javascript to break the law of non-contradiction, or, at least, convincingly make it look like it's breaking the law of non-contradiction. Now I'm trying to make all four of the above code examples give the unexpected result.
What would be a good way to go about this?
The best I can do is:
[] == ![] // true
or
var a = [];
a == !a
Of course this is really doing [] == false // true and !![] == ![] // false. It's really just a technicality.
EDIT: This is really a joke, but does work:
var a = false; var b = function() { return a = !a };
console.log(!!(b() && !b())); // true
console.log(b() == !b()); // true
console.log(b() === !b()); // true
console.log(b() || !b()); // true
This one will do the trick:
var a = '0';
a == !a
(evaluates to true)
In this case, a == false and !a == false.
a=NaN;
var a=NaN,
A=[(a && !a), (a == !a),(a === !a),(a || !a)];
alert(A)
/* returned value: (Array)
NaN,false,false,true
*/
I still haven't found anything to break && and ===, but here's one for == and ||:
Object.prototype.toString = function() {
return false;
};
a = {};
b = (a || !a);
alert(a || !a); //alerts false
alert(b == !b); //alerts true

Categories

Resources