OR operator with real numbers - javascript

Why is the mid number result of this statement?
(0 || 0.571428571428571 || 1) == 0.571428571428571
How the comparsion works?
Well. Looks like stupid question. For those who works in php where this statement has a different result could be helpfull to know that JS will return number instead bool.

|| is a short-circuiting operator. It evaluates its left-hand operand, and returns that if it's truthy, otherwise it evaluates and returns its right-hand operator. When you have a sequence of || operators, it performs this left-to-right, returning the first truthy value (or the last value if none are truthy).
In your example, 0 is falsey, so 0.571428571428571 is the first truthy value, and it's returned.

Your expression is interpreted as
((0 || 0.571428571428571) || 1)
The result of the first || is truthy, so that's the result of the overall expression. That's how || works: the result is the left-hand operand if it's truthy, or else the right-hand operand.

The answer to this lies in the fact that 0 is considered a false value while non-zero numbers are considered true.
Since || and && will short circuit and return as soon as it knows the outcome. For OR expressions this means that the first truthy value will be returned. For AND expressions it means the first false value is returned:
(true && true && 0 && true) === 0
(false && false && 1) === 1
(false || false || 1 || false) === 1
(false || false || 0) === 0
Since the first value in your expression is a falsey value, it is not returned but the floating point is a truthy value, so it is returned.

Related

Javascript short circuiting in if statement

I am confused about the below if statement code. Not sure what it is exactly doing
if (this.props.filterURL && nextProps.filterURL !== this.props.filterURL) {}
Can someone please help me to understand this?
Is it a short-circuiting in if statement:
i.e
1- if first this.props.filterURL from left side is false then it will return false. 2- if first this.props.filterURL has a value then it will return true and the second variable nextProps.filterURL will be compared to this.props.filterURL on the right most of the statement?
Notes :
This short-circuiting is good for the performance, as it allows significant bits of calculations to be skipped.
The AND operator (&&) returns true if both expressions are true, otherwise it returns false.
DEMO
var x = 1;
var y = 5;
if (x > 0 && y < 6) { console.log(x) }; // true
if(x > 1 && y < 6) { console.log(x) }; // false
As suggested by nnnnnn in his comment, the first this.props.filterURL is checking for a truthy value, not for true specifically. If the property is not defined that is falsy, but if the value is null or 0 or an empty string those are all falsy too.
In case of AND operator it evaluates the second expression only if the first one is true.
In your case,
if (this.props.filterURL && nextProps.filterURL !== this.props.filterURL) {}
can be interpreted as if(expr1 && expr2)
where expr1= this.props.filterURL and expr2 = nextProps.filterURL !== this.props.filterURL
for first expression expr1 it evaluates whether it is not null or undefined...
for the second expression expr2 nextProps.filterURL !== this.props.filterURL it checks both the value and data type. So for example if you have both value as same 1234 but for one it is of type String and for another it is for number, this condition would be true.

JavaScript && Operator used for returns

I am working understanding a JavaScript library and I came across this statement:
const assetsManifest = process.env.webpackAssets && JSON.parse(process.env.webpackAssets)
Then later on in the library, it uses the assetsMannifest like an object e.g.
assetsManifest['/vendor.js']
I thought the && operator was only used to return boolean values in logical checks. Can someone explain to me what is going on here?
Many thanks,
Clement
This operator doesn't always return true or false. It doesn't work like in some other programming languages. In JavaScript && operator returns the first value if it's falsy or the second one if not.
Examples:
null && 5 returns null because null is falsy.
"yeah yeah" && 0 returns 0 because every string is truthy.
Not so obvious :-)
Further reading:
Why don't logical operators (&& and ||) always return a boolean result?
&& returns first value converting to false or last value converting to true. It's because no need to calculate full logical condition with && if first value is falsy
console.log(55 && 66);
console.log(0 && 77);
console.log(88 && 0);
Also you can use && or || as if operator:
if (itsSunny) takeSunglasses();
equals to
itsSunny && takeSunglasses();
in that context it is checking if process.env.webpackAssets is a truthy value. If it is it will evaluate and return the next part. in this case JSON.parse(process.env.webpackAssets)
The logic is essentially
if (process.env.webpackAssets) {
return JSON.parse(process.env.webpackAssets)
}
else {
return process.env.webpackAssets // (null | undefined | 0 | '' | false)
}
Both && and || are evaluting there arguments in lazy mode and return the last value, after witch the result is known.
123 && (0 || '' && 78) || 7 && 8 || [] && {} || 90 || 77 && 13
###_^^ both results are possible 123 && ???
#_^^ first part is falsy, resume 0 || ??
#####_^^ can't be true, return ''
^^_########## 0 || '' return ''
^^_################ return ''
#######################_^^ resume
#_^^ resume
^^_# return 8
^^_###### return 8
^^_########################## drop
And the result is 8.

Why `int(0) and boolean` returns `int(0)` instead `boolean(false)`?

Specifically (I don't know if it can happen in others case), when I do int(0) && boolean with myString.length && myString === "true" when myString = "", it returns 0 instead of returns a boolean.
alert((function() {
var myString = "";
return myString.length && myString === "true";
})());
I know that I can fix it by do myString.length !== 0 or casting with Boolean. But I like to understand why && don't force cast the left side to boolean.
Live example: http://jsfiddle.net/uqma4ahm/1/
The && operator in JavaScript returns the actual value of whichever one of its subexpression operands is last evaluated. In your case, when .length is 0, that expression is the last to be evaluated because 0 is "falsy".
The operator does perform a coercion to boolean of the subexpression value(s), but it only uses that result to determine how to proceed. The overall value of the && is thus not necessarily boolean; it will be boolean only when the last subexpression evaluated had a boolean result.
This JavaScript behavior is distinctly different from the behavior of the similar operator in C, C++, Java, etc.
The && operator yields the left hand value if it is false-y1 and the right-hand value otherwise. (Unlike some languages, it is not guaranteed to evaluate to true or false!)
TTL for A && B:
A B (A && B)
false-y - A
truth-y - B
To make sure that only true or false is returned, it is easy to apply (double) negation:
return !!(myString.length && myString === "true")
or, equivalently
return !(!myString.length || myString !== "true")
Here is the negation TTL which leads to deriving !!(false-y) => false and !!(truth-y) => true.
A !A !(!A)
false-y true false
truth-y false true
1 In JavaScript the false-y values are false 0, "", null, undefined, NaN. While everything else is truth-y.

0 vs '0' with boolean operators

0 == false and '0' == false are both 'true'
However, (true && 0) is 'false', while (true && '0') is 'true'.
Why?
The abstract comparison (==) rules are described in ES5 11.9.3 while the rules for logical operators (&&) are described in ES5 11.11.
In short, == is just more complex than &&. Where && just uses the internal ToBoolean() to evaluate its operands, == has various conditions that may result in the use of ToBoolean(), ToNumber(), and/or ToPrimitive().
(0 == false) == true:
7. If Type(y) is Boolean, return the result of comparison x == ToNumber(y)
ToNumber(false) === 0, so 0 == 0, so true.
('0' == false) == true:
This also passes through step 7, resulting in '0' == 0.
Then, starting over at the top, it reaching step 5:
5. If Type(x) is String and Type(y) is Number,
return the result of the comparison ToNumber(x) == y.
ToNumber('0') === 0, so again 0 == 0, and again true.
!!(true && 0) == false
&& simply returns the 1st operand if it's falsy (ToBoolean(...) === false), or the 2nd operand.
It's strictly (true && 0) === 0.
And, when used as an if condition, the result (0) will as well be passed through ToBoolean(...) and ToBoolean(0) === false.
!!(true && '0') == true
Again, this returns the 2nd operand, '0'.
This time, however, ToBoolean('0') === true as '0' is a non-empty String, making it truthy.
Also, if you want simpler comparison rules, use strict comparison (===, 11.9.6).
'0' (or any non-empty string) is 'truthy' in JS. The == operator, however, does some strange type-coercion which is why many prominent JS figures including Crockford highly discourage it. This is a good example of why you should avoid it, it takes the string '0' and coerces it into a falsey value.
Here's a link that explains this process:
http://webreflection.blogspot.com/2010/10/javascript-coercion-demystified.html
If Type(x) is Boolean, return the result of the comparison
ToNumber(x) == y: false == 0 and true == 1 but true != 2
So even stranger than your example is this:
('1' == true) // true
('2' == true) // false!

returning with &&

What does it mean to return a value with &&?
else if (document.defaultView && document.defaultView.getComputedStyle) {
// It uses the traditional ' text-align' style of rule writing,
// instead of textAlign
name = name.replace(/([A-Z]) /g, " -$1" );
name = name.toLowerCase();
// Get the style object and get the value of the property (if it exists)
var s = document.defaultView.getComputedStyle(elem, " ") ;
return s && s.getPropertyValue(name) ;
return a && b means "return a if a is falsy, return b if a is truthy".
It is equivalent to
if (a) return b;
else return a;
The logical AND operator, &&, works similarly. If the first object is falsy, it returns that object. If it is truthy, it returns the second object. (from https://www.nfriedly.com/techblog/2009/07/advanced-javascript-operators-and-truthy-falsy/).
Interesting stuff!
EDIT:
So, in your case, if document.defaultView.getComputedStyle(elem, " ") does not return a meaningful ("truthy") value, that value is returned. Otherwise, it returns s.getPropertyValue(name).
The AND && operator does the following:
Evaluate operands from left to right.
For each operand, convert it to a boolean. If the result is false, stop and return the original value of that result.
If all other operands have been assessed (i.e. all were truthy), return the last operand.
As I said, each operand is convert to a boolean, if it's 0 it's falsy and every other value different than 0 (1, 56, -2, etc etc) are truthy
In other words, AND returns the first falsy value or the last value if none were found.
// if the first operand is truthy,
// AND returns the second operand:
return 1 && 0 // 0
return 1 && 5 // 5
// if the first operand is falsy,
// AND returns it. The second operand is ignored
return null && 5 // null
return 0 && "no matter what" // 0
We can also pass several values in a row. See how the first falsy one is returned:
return 1 && 2 && null && 3 // null
When all values are truthy, the last value is returned:
return 1 && 2 && 3 // 3, the last one
You can learn more about the logical operator here https://javascript.info/logical-operators

Categories

Resources