Reason for boolean switching when minifying js - javascript

I have this line of code in a js file
var useScroll = Window.innerWidth > 1360 ? true : false;
When it's minified it becomes
i=Window.innerWidth>1360?!0:!1
I was just curious, why have the ! operator? To me it makes more sense to just be.
i=Window.innerWidth>1360?1:0

The ! operator does casting. So !0 becomes true and !1 becomes false. However, 0 and 1 are numbers, not booleans.

There is a very valid reason. 1 and 0 are integeers, and does sometimes behave different than booleans.
However the ! operator includes casting, which menas that !0 and !1 are acutal booleans, but they are shorter to type than false and true. And that is the reason they are beeing used.
Example where they behave different:
var a = (1 === true); //a will be false
var a = (!0 === true); //a will be true
However you can simplify your code to
i=Window.innerWidth>1360
since Window.innerWidth>1360 will be either true or false which is exactly what you are looking for.

if you do !0 or !1 it will become a boolean, if you remove ! it will be an integer...
And instead of doing
Window.innerWidth > 1360 ? true : false
do
Window.innerWidth > 1360

The ! is (logical NOT) operator So !0 become true and !1 becomes false. Where only 0 and 1 are numbers not boolean.
var n1 = !true; // !t returns false
var n2 = !false; // !f returns true
var n3 = !'Cat'; // !t returns false
So, both have a different meaning by data types.
i=Window.innerWidth>1360?1:0 This is also valid as you told but when you want data type as boolean you can't get by using this expression.

Related

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.

How does Type Coercion in Javascript in the case of object to boolean?

To the best of my knowledge, (x == false) should do the same thing as !x, as both of them try to interpret x as a boolean, and then negates it.
However, when I tried to test this out, I started getting some extremely strange behavior.
For example:
false == [] and false == ![] both return true.
Additionally
false == undefined and true == undefined both return false, as does
false == Infinity and true == Infinity and
false == NaN and true == NaN.
What exactly is going on here?
http://jsfiddle.net/AA6np/1/
It's all here: http://es5.github.com/#x11.9.3
For the case of false == []:
false is converted to a number (0), because that is always done with booleans.
[] is converted to a primitive by calling [].valueOf().toString(), and that is an empty string.
0 == "" is then evaluated by converting the empty string to a number, and because the result of that is also 0, false == [] is true.
For the case of false == ![]:
The logical not operator ! is performed by returning the opposite of ToBoolean(GetValue(expr))
ToBoolean() is always true for any object, so ![] evaluates to false (because !true = false), and therefore is false == ![] also true.
(false == undefined) === false and (true == undefined) === false is even simpler:
false and true are again converted to numbers (0 and 1, respectively).
Because undefined cannot be compared to a number, the chain bubbles through to the default result and that is false.
The other two cases are evaluated the same way: First Boolean to Number, and then compare this to the other number. Since neither 0 nor 1 equals Infinity or is Not A Number, those expressions also evaluate to false.
The abstract equality algorithm is described in section 9.3 of the specification.
For x == y where x = false and y = []:
Nope. Types are not equal.
Nope, x is not null.
Nope. x is not undefined.
Nope, x is not a number
Nope, x is not a string.
Yes, x is a boolean, so we compare ToNumber(x) and y.
Repeat the algorithm, x=0 and y=[].
We end at step 8:Type(x) == number. and Type(y) == object.
So, let the result be x == ToPrimitive(y).
ToPrimitive([]) == ""
Now, repeat the algorithm again with x=0 and y="". We end at 4: "return the result of the comparison x == ToNumber(y)."
ToNumber("") == 0
The last repetition of the algorithm ends at step 1 (types are equal). By 1.c.iii, 0 == 0, and true is returned.
The other results can be obtained in a similar manner, by using the algorithm.
false == []
Using == Javascript is allowed to apply conversions. The object will convert into a primitive to match type with the boolean, leaving an empty string. The false will convert into a number 0. The compares the empty string and the number 0. The string is converted to a number which will be 0, so the expression is "true"
![]
Javascript converts the object to the boolean true, therefore denying true ends being false.
false == undefined true == undefined
false == Infinity and true == Infinity
false == NaN and true == NaN
Again a bit of the same! false is converted to 0, true to 1. And then, undefined is converted to a number which is... NaN! So false in any case
I would recommend to use === !== as much as you can to get "expected" results unless you know very well what you are doing. Using something like Boolean(undefined) == false would also be nice.
Check ECMAScript specifications for all the details when converting stuff.

How safe is using var t=!0 / var t=!1 for true / false? Do they always return true boolean true / false?

Many of us have seen / use the following:
var t=!0; (t will equal true)
var t=!1; (t will equal false)
How safe is this method of evaluating true / false?
I see google use this all the time.
Will these ALWAYS return a boolean true / false?
Thanks.
Yes:
11.4.9 Logical NOT Operator ( ! )
The production UnaryExpression : ! UnaryExpression is evaluated as
follows:
Let expr be the result of evaluating UnaryExpression.
Let oldValue be ToBoolean(GetValue(expr)).
If oldValue is true, return false.
Return true.
Source: http://es5.github.com/x11.html#x11.4.9
Yes, they'll always return true and false.
More specifically, !x will return true for any "falsey" value (undefined, "", etc) and conversely return false for any "truthy" value.
A more common idiom is !!x which converts any "falsey" value to strictly false and any "truthy" value to strictly true - in other words it's like a "type cast" to a boolean.

Javascript Logical Operator:?

I was examining the src of underscore.js and discovered this:
_.isRegExp = function(obj) {
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
};
Why was "!!" used? Should it be read as NOT-NOT or is there some esoteric JS nuance going on here?
It is just an obtuse way to cast the result to a boolean.
Yes, it's NOT-NOT. It is commonly used idiom to convert a value to a boolean of equivalent truthiness.
JavaScript understands 0.0, '', null, undefined and false as falsy, and any other value (including, obviously, true) as truthy. This idiom converts all the former ones into boolean false, and all the latter ones into boolean true.
In this particular case,
a && b
will return b if both a and b are truthy;
!!(a && b)
will return true if both a and b are truthy.
The && operator returns either false or the last value in the expression:
("a" && "b") == "b"
The || operator returns the first value that evaluates to true
("a" || "b") == "a"
The ! operator returns a boolean
!"a" == false
So if you want to convert a variable to a boolean you can use !!
var myVar = "a"
!!myVar == true
myVar = undefined
!!myVar == false
etc.
It is just two ! operators next to each other. But a double-negation is pointless unless you are using !! like an operator to convert to Boolean type.
It will convert anything to true or false...

How do I check if a number evaluates to infinity?

I have a series of Javascript calculations that (only under IE) show Infinity depending on user choices.
How does one stop the word Infinity appearing and for example, show 0.0 instead?
if (result == Number.POSITIVE_INFINITY || result == Number.NEGATIVE_INFINITY)
{
// ...
}
You could possibly use the isFinite function instead, depending on how you want to treat NaN. isFinite returns false if your number is POSITIVE_INFINITY, NEGATIVE_INFINITY or NaN.
if (isFinite(result))
{
// ...
}
In ES6, The Number.isFinite() method determines whether the passed value is a finite number.
Number.isFinite(Infinity); // false
Number.isFinite(NaN); // false
Number.isFinite(-Infinity); // false
Number.isFinite(0); // true
Number.isFinite(2e64); // true
A simple n === n+1 or n === n/0 works:
function isInfinite(n) {
return n === n/0;
}
Be aware that the native isFinite() coerces inputs to numbers. isFinite([]) and isFinite(null) are both true for example.
Perform the plain ol’ comparison:
(number === Infinity || number === -Infinity)
or to save several characters:
Math.abs(number) === Infinity
Why to use this
!(Number.isFinite(number)) breaks on NaN inputs.
Number.POSITIVE_INFINITY and Number.NEGATIVE_INFINITY can be redefined; they are configurable.
Infinity and -Infinity are read-only in the strict mode.
It is the shortest solution.
Actually n === n + 1 will work for numbers bigger than 51 bit, e.g.
1e16 + 1 === 1e16; // true
1e16 === Infinity; // false
I like to use Lodash for a variety of defensive coding reasons as well as readability. ES6 Number.isFinite is great and does not have issues with non-numeric values, but if ES6 isn't possible, you already have lodash, or want briefer code: _.isFinite
_.isFinite(Infinity); // false
_.isFinite(NaN); // false
_.isFinite(-Infinity); // false
_.isFinite(null); // false
_.isFinite(3); // true
_.isFinite('3'); // true
I've ran into a scenario that required me to check if the value is of the NaN or Infinity type but pass strings as valid results. Because many text strings will produce false-positive NaN, I've made a simple solution to circumvent that:
const testInput = input => input + "" === "NaN" || input + "" === "Infinity";
The above code converts values to strings and checks whether they are strictly equal to NaN or Infinity (you'll need to add another case for negative infinity).
So:
testInput(1/0); // true
testInput(parseInt("String")); // true
testInput("String"); // false
You can use isFinite in window, isFinite(123):
You can write a function like:
function isInfinite(num) {
return !isFinite(num);
}
And use like:
isInfinite(null); //false
isInfinite(1); //false
isInfinite(0); //false
isInfinite(0.00); //false
isInfinite(NaN); //true
isInfinite(-1.797693134862316E+308); //true
isInfinite(Infinity); //true
isInfinite(-Infinity); //true
isInfinite(+Infinity); //true
isInfinite(undefined); //true
You can also Number.isFinite which also check if the value is Number too and is more accurate for checking undefined and null etc...
Or you can polyfill it like this:
Number.isFinite = Number.isFinite || function(value) {
return typeof value === 'number' && isFinite(value);
}

Categories

Resources