How to write shorter control statements in javascript - javascript

If i want to test two properties of one in javascript i have to write
((a test b ) && (a test c))
is there a way to write something like
(a test ( b && c))
for example
if(a === NaN || a === Infinity){…}
to
if (a === (NaN || Infinity)){…}
Just wondering if there were shorthands like this.

Sadly, no.
if (a === (NaN || Infinity)){…} would test a === Infinity. First it would check (NaN || Infinity) (evaluates to Infitity), the check.
Additionally, checking against NaN always returns false. Try it: NaN === NaN. Use isNaN(a) instead.

Yes, there is a shortcut:
if ([val1, val2, val3 /*...*/].indexOf(a) > -1){ /* ... */ }
or even shorter:
if (~[val1, val2, val3 /*...*/].indexOf(a)){ /* ... */ }
Note it won't work with NaN, because comparing to NaN is useless. Even NaN == NaN is false, that's why there are isNaN and Number.isNaN.

Related

Is the JavaScript operator === provably transitive?

JavaScript's quirky weakly-typed == operator can easily be shown to be non-transitive as follows:
var a = "16";
var b = 16;
var c = "0x10";
alert(a == b && b == c && a != c); // alerts true
I wonder if there are any similar tricks one can play with roundoff error, Infinity, or NaN that could should show === to be non-transitive, or if it can be proved to indeed be transitive.
The === operator in Javascript seems to be as transitive as it can get.
NaN is reliably different from NaN:
>>> 0/0 === 0/0
false
>>> 0/0 !== 0/0
true
Infinity is reliably equal to Infinity:
>>> 1/0 === 1/0
true
>>> 1/0 !== 1/0
false
Objects (hashes) are always different:
>>> var a = {}, b = {};
>>> a === b
false
>>> a !== b
true
And since the === operator does not perform any type coercion, no value conversion can occur, so the equality / inequality semantics of primitive types will remain consistent (i.e. won't contradict one another), interpreter bugs notwithstanding.
If you look at the spec (http://bclary.com/2004/11/07/#a-11.9.6) you will see that no type coercion is being made. Also, everything else is pretty straightforward, so maybe only implementation bugs will make it non-transitive.
Assuming you have variable a,b, and c you can't be 100% certain as shown here. If someone is doing something as hackish as above in production, well then you probably have bigger problems ;)
var a = 1;
var b = 1;
Object.defineProperty(window,"c",{get:function(){return b++;}});
alert(a === b && b === c && a !== c); // alerts true

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

If condition checking for two TextFields Value

if(a.value === undefined || a.value.length>37 ||
b.value === undefined || b.value.length > 256) {
If the first one is undefined or greater than a length of 37. I get a error, but it does not check for the second field at all.
use parenthesis. It checks from left to right and stops once it hits a fail the way you have it set up.
Try
if((a.value === undefined || a.value.length>37) ||
(b.value === undefined || b.value.length > 256)) {
Conditional evaluation is lazy, i.e. it stops as soon as the result has been determined. That is, if (A && B) will not evaluate B if A is false, because the conjunction will have to be false already, and similarly if (A || B) will not evaluate B if A is true because the disjunction is already true.
You're forgetting what an OR in logic means. It only going to check until it finds one true statement.
Try regrouping:
((a.value === undefined || a.value.length>37)
||
(b.value === undefined || b.value.length > 256))
Just about elevating the condition a bit, and bringing a more broad result back instead of chasing the first true response.

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