var result='16'>'141';
console.log(result);
var result='16'>141;
console.log(result);
That’s because if any of the operands is not string, then both
operands become numbers, and the comparison becomes correct.
Can anyone tell me. How below equation is evaluate?
var result='a'>11;
console.log(result);
'a'>11=> Answer should be true instead of false;
because
'a' will convert to int 97 > 11 => true then how it evaluate false.
If I go like this 'a'>'11' => then it answer comes true.
var result='a'>'11';
console.log(result);
When you convert a non-numeric string like 'a' to a Number, you get NaN:
console.log(+'a'); // NaN
console.log('a' * 1); // NaN
console.log(Number('a')); // NaN
And NaN always produces false in relational comparisons. Trichotomy does not hold:
console.log(NaN < 0); // false
console.log(NaN > 0); // false
console.log(NaN == 0); // false
If you want to convert 'a' to 97, use charCodeAt:
console.log('a'.charCodeAt(0)); // 97
Javscript use The Abstract Equality Comparison Algorithm
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
When comparing a string and a number, string is converted to a number, but you are thinking like some ASCII code.
Since 'a' is not a number so it's comparison with a number will give you false in any case > , < or ==.
Related
The comparison operators like > and < return Boolean value when their input is given as two string values.
I tried few examples:
/* String vs String */
console.log('firstName' < 'lastname'); // true
console.log('firstName' < 'Firstname'); // false
console.log('!firstName' < 'lastname'); // true
console.log('!firstName' < 'Firstname'); // true
console.log('!firstName' < '!Firstname'); // false
console.log('!firstName' < '_!Firstname'); // true
console.log('#!firstName' < '_!Firstname'); // true
console.log('#!firstName' < '2_!Firstname'); // false
/* String vs Number */
console.log('#!firstName' < 2); // false
console.log('#!firstName' < -1); // false
/* String vs Special Numbers */
console.log('#!firstName' < Infinity); // false
console.log('#!firstName' < -Infinity); // false
console.log('#!firstName' < -Infinity + Infinity); // false
/* String vs NaN */
console.log('#!firstName' < NaN); // false
console.log(NaN.toString()); // "NaN"
console.log('#!firstName' < "NaN"); // true
/* String vs Arrays */
console.log('firstName' < [Infinity, -Infinity]); // false
console.log('firstName' < ['Firstname', Infinity, -Infinity]); // false
console.log('firstName' < ['2_Firstname', Infinity, -Infinity]); // false
I'm really curious to know how JavaScript really evaluates such expressions. In the above examples, I find this one as the most fascinating one console.log('#!firstName' < Infinity); // false.
So, the question I have is:
How is the comparison done using "is greater than" and "is
less than" operators in JavaScript in these scenarios (from above examples):
String vs String,
String vs Number,
String vs Special Numbers,
String vs NaN,
String vs Arrays
As said above, the formal specification is in the standard: http://www.ecma-international.org/ecma-262/7.0/#sec-abstract-relational-comparison , in layman's terms the logic is like this:
1) String vs String
Split both strings into 16-bit code units and compare them numerically. Note that code units != characters, e.g. "cafè" < "cafè" is true (really).
2) String vs other primitive
Convert both to numbers. If one of them is NaN, return false, otherwise compare numerically. +0 and -0 are considered equal, +/-Infinity is bigger/smaller than anything else.
3) String vs Object
Try to convert the object to a primitive, attempting, in order, [Symbol.toPrimitive]("number"), valueOf and toString. If we've got string, proceed to 1), otherwise proceed to 2). For arrays specifically, this will invoke toString which is the same as join.
String, String comparison is based on Unicode ordering (a is greater than A).
String, Number comparison first converts the string into a number before comparing (same with infinity).
String, Array comparison first converts the array into a string and then compares as above.
Javascript String Comparison
Javascript Object Comparison
The precise steps to take are described in the specification, which specifically describes what to do in the case that one (or both) sides of the comparison are NaN or +Infinity or -Infinity. For px < py, for example, the less-than operator calls the Abstract Relational Comparison Algorithm:
11.8.5 The Abstract Relational Comparison Algorithm
(If both items being compared are not strings, then:)
Let nx be the result of calling ToNumber(px). Because px and py are primitive values evaluation order is not important.
Let ny be the result of calling ToNumber(py).
If nx is NaN, return undefined.
If ny is NaN, return undefined.
If nx and ny are the same Number value, return false.
If nx is +0 and ny is −0, return false.
If nx is −0 and ny is +0, return false.
If nx is +∞, return false.
If ny is +∞, return true.
If ny is −∞, return false.
If nx is −∞, return true.
If the mathematical value of nx is less than the mathematical value of ny —note that these mathematical values are both finite and not both zero—return true. Otherwise, return false.
Else, both px and py are Strings
If py is a prefix of px, return false. (A String value p is a prefix of String value q if q can be the result of concatenating p and some other String r. Note that any String is a prefix of itself, because r may be the empty String.)
If px is a prefix of py, return true.
Let k be the smallest nonnegative integer such that the character at position k within px is different from the character at position k within py. (There must be such a k, for neither String is a prefix of the other.)
Let m be the integer that is the code unit value for the character at position k within px.
Let n be the integer that is the code unit value for the character at position k within py.
If m < n, return true. Otherwise, return false.
When both items being compared are strings, it effectively results in the code points of each character being compared. For example, 'firstName' < 'lastname' because the character code of f (102) is smaller than the character code of l (108). For '!firstName' < 'Firstname', the character code of ! (33) is smaller than the character code of F (70), so that evaluates to true as well. See the following snippet for an example of the implementation:
function compare(left, right) {
for (let i = 0; i < left.length; i++) {
const c1 = left[i].charCodeAt();
const c2 = right[i].charCodeAt();
if (c1 !== c2) {
console.log('Char code comparision:', c1 < c2, '< comparison:', left < right);
break;
}
}
}
/* String vs String */
compare('firstName', 'lastname'); // true
compare('firstName', 'Firstname'); // false
compare('!firstName', 'lastname'); // true
compare('!firstName', 'Firstname'); // true
compare('!firstName', '!Firstname'); // false
compare('!firstName', '_!Firstname'); // true
compare('#!firstName', '_!Firstname'); // true
compare('#!firstName', '2_!Firstname'); // false
Just for interest. We have that NaN is spreading along side calculation.
1 + NaN => NaN
Is there any operator which will stop this spreading. I mean something like:
<operator> NaN => number
or
NaN <operator> <operand> => number
or
<operand> <operator> NaN => number
NaN => number
Actually in Ecmascript definition of (**) operator for numbers. Has a special case when second operand is +0 or -0.
https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-exponentiate
So actually:
console.log(NaN ** 0) // will log 1
The Javascript has a built-in method that detect a NaN, but you will need check this "Possible number" for each operand.
let possibleNumber = "4f";
console.log(isNaN(Number(possibleNumber)));
possibleNumber = "44";
console.log(isNaN(Number(possibleNumber)));
Output:
true
false
You can do some function to check and return some number that you want
function checkIfIsNaN(number,numIfTrue,numIfFalse){
if(isNaN(Number(number))){ return numIfTrue} else{return numIfFalse};
}
console.log(checkIfIsNaN("44",4,10));
I'm using node.js with v8.11.3.
parseInt("") returns NaN, but isNaN("") returns false:
console.log(
parseInt(''),
isNaN('')
);
another example:
console.log(
parseFloat('0x5'),
parseInt('0x5')
);
Per MDN docs, parseInt:
If the first character cannot be converted to a number, parseInt returns NaN.
There is no first character in the empty string - it cannot be converted to a number, so NaN is returned.
But isNaN is different. As the first paragraph of MDN says:
Note: coercion inside the isNaN function has interesting rules; you may alternatively want to use Number.isNaN(), as defined in ECMAScript 2015.
...
When the argument to the isNaN function is not of type Number, the value is first coerced to a Number.
The empty string, when coerced to a Number, is 0:
const result = Number('');
console.log(result + ' : ' + typeof result);
You might try using parseInt and then checking to see if the result is NaN or not:
const possibleInt = parseInt('');
console.log(Number.isNaN(possibleInt));
The use of Number() just shuffles the problem around. For example:
parseInt("14px"); // 14
parseInt("abc"); // NaN
parseInt(""); // NaN (i.e. null string is a number)
versus use of isNaN:
isNaN("14px"); // false
isNaN("abc"); // true
isNaN(""); // false
versus use of Number():
Number("14px"); // NaN
Number("abc"); // NaN
Number(""); // 0
And, making it more complicated, you can't even do:
parseInt(x) == NaN ? 0 : parseInt(x);
because comparisons with NaN are always false, even NaN == NaN is false.
The simplest that I found was:
x=="" || !isNaN(x) ? 0 : parseInt(x);
but this assumes that the null string is the only anomaly, so it may not work in all cases.
If i execute the following lines in thw browser console
!![] //--- returns true
!!0 //--- returns false
I get that [] and 0 have different boolean values.
I don't understand why
[] == 0 //--- returns true
returns true.
What am I missing?
Remember that array is object and 0 is number.
And as "user2864740" told..
1) When you doing
!![] //--- returns true
!!0 //--- returns false
You are performing so called "ToBoolean" convertion
https://es5.github.io/#x9.2
Number
The result is false if the argument is +0, −0, or NaN; otherwise the
result is true.
Object ( our [] )
always true
2) But when you using == you performing so called "Equality Comparison"
https://es5.github.io/#x11.9.3
Here thins a little bit complicated but to understand what happens you have to remember that == do a type coercion ( so you can compare oranges to apples :) )
First of all compiler converts [] to some primitive type.
If Type(x) is either String or Number and Type(y) is Object, return
the result of the comparison x == ToPrimitive(y).
How ToPrimitive works is a matter of an article :), but's it easy to remember that closet primitive type to array is string. Array will be converted to empty string.
[].toString() === ""
So now we need to compare empty string and number 0
"" == 0 // true
Hmmm. So it's true. But why is that? Remember that when you compare with "Equality Comparison" number and string
If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
So let's try to convert empty string to number
Number("") === 0
And in the end
0 === 0
I hope that's explains something :)
JavaScript is probably converting the array to a number:
!!Number([]) // false
Number([]) == 0 // true
I store some parameters client-side in HTML and then need to compare them as integers. Unfortunately I have come across a serious bug that I cannot explain. The bug seems to be that my JS reads parameters as strings rather than integers, causing my integer comparisons to fail.
I have generated a small example of the error, which I also can't explain. The following returns 'true' when run:
console.log("2" > "10")
Parse the string into an integer using parseInt:
javascript:alert(parseInt("2", 10)>parseInt("10", 10))
Checking that strings are integers is separate to comparing if one is greater or lesser than another. You should always compare number with number and string with string as the algorithm for dealing with mixed types not easy to remember.
'00100' < '1' // true
as they are both strings so only the first zero of '00100' is compared to '1' and because it's charCode is lower, it evaluates as lower.
However:
'00100' < 1 // false
as the RHS is a number, the LHS is converted to number before the comparision.
A simple integer check is:
function isInt(n) {
return /^[+-]?\d+$/.test(n);
}
It doesn't matter if n is a number or integer, it will be converted to a string before the test.
If you really care about performance, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
return function(n) {
return re.test(n);
}
}());
Noting that numbers like 1.0 will return false. If you want to count such numbers as integers too, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
var re2 = /\.0+$/;
return function(n) {
return re.test((''+ n).replace(re2,''));
}
}());
Once that test is passed, converting to number for comparison can use a number of methods. I don't like parseInt() because it will truncate floats to make them look like ints, so all the following will be "equal":
parseInt(2.9) == parseInt('002',10) == parseInt('2wewe')
and so on.
Once numbers are tested as integers, you can use the unary + operator to convert them to numbers in the comparision:
if (isInt(a) && isInt(b)) {
if (+a < +b) {
// a and b are integers and a is less than b
}
}
Other methods are:
Number(a); // liked by some because it's clear what is happening
a * 1 // Not really obvious but it works, I don't like it
Comparing Numbers to String Equivalents Without Using parseInt
console.log(Number('2') > Number('10'));
console.log( ('2'/1) > ('10'/1) );
var item = { id: 998 }, id = '998';
var isEqual = (item.id.toString() === id.toString());
isEqual;
use parseInt and compare like below:
javascript:alert(parseInt("2")>parseInt("10"))
Always remember when we compare two strings.
the comparison happens on chacracter basis.
so '2' > '12' is true because the comparison will happen as
'2' > '1' and in alphabetical way '2' is always greater than '1' as unicode.
SO it will comeout true.
I hope this helps.
You can use Number() function also since it converts the object argument to a number that represents the object's value.
Eg: javascript:alert( Number("2") > Number("10"))
+ operator will coerce the string to a number.
console.log( +"2" > +"10" )
The answer is simple. Just divide string by 1.
Examples:
"2" > "10" - true
but
"2"/1 > "10"/1 - false
Also you can check if string value really is number:
!isNaN("1"/1) - true (number)
!isNaN("1a"/1) - false (string)
!isNaN("01"/1) - true (number)
!isNaN(" 1"/1) - true (number)
!isNaN(" 1abc"/1) - false (string)
But
!isNaN(""/1) - true (but string)
Solution
number !== "" && !isNaN(number/1)
The alert() wants to display a string, so it will interpret "2">"10" as a string.
Use the following:
var greater = parseInt("2") > parseInt("10");
alert("Is greater than? " + greater);
var less = parseInt("2") < parseInt("10");
alert("Is less than? " + less);