I'm having confusion about if-statement in javascript - javascript

I have a condition in javascript like this :
var a = '60';
var b = '500';
if(a < b) {
console.log('true');
} else {
console.log('false');
}
but the result is false, my expectation should be true, but i tried to compare with php code :
<?php
$a = '60';
$b = '501';
if($a < $b) {
echo 'true';
} else {
echo 'false';
}
?>
and the result is true, if in javascript there is no else if condition it will automatically read to the false condition if the value is not true?

If you're expecting a and b to behave like numbers, don't put them in quotes. That makes them strings.
var a = 60;
var b = 500;
PHP automatically converts those to a number. Try running echo $a - 1; You'll get 59. Also try "00001" == "1". You'll get true! JavaScript doesn't do this kind of detection. Instead JavaScript compares strings alphabetically by their char codes. By alphabetically, I mean that it compares the first characters of each string. If they have the same char codes, it moves on to the next character of each string. If one has a higher char code than the other, it is "greater" than the other string- much like we do when we're determining if "dog" or "dot" comes first alphabetically. In this case, JavaScript would see that 6 has a char code of 54, and 5 has a char code of 53, and it would conclude right then and there that "60" is greater than "500".

PHP converts both strings to numbers before comparing them. If you want the same in JavaScript, use:
if (parseInt(a, 10) < parseInt(b, 10)) {
This is documented:
If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.

Good question. The if-else statement is correct, but the variables are not set correctly.
You can use var, but you should use let or const. (but that is just a semantic thing)
The REAL reason you are having issues is that you are putting your numbers as strings..so literally, '60' is not less than '500'.
var a = 60;
var b = 500;
in this case it would come out true. 60 is, in fact, less then 500 =).
Keep up the good work.

You should avoid adding quotes in numbers but in case it is present there then you
can convert to number using parseInt.
Try this:
var a = '60';
var b = '500';
if(parseInt(a) < parseInt(b)) {
console.log('true');
} else {
console.log('false');
}

this is not the case Javascript supports if,else if and else statements but in your code you have declared the values as strings so the compiler is not comparing the strings directly so you have to pass your variables a and b to "Number" function of javascript which will convert strings to integer.
var a = '60';
var b = '500';
var aint = Number(a);
var bint = Number(b);
if(aint < bint) {
console.log('true');
}
else if(aint>bint){
console.log('a is greater');
}else {
console.log('false');
}
Output: true

Related

getting wrong answer for finding largest of 2 numbers using readline-sync in js [duplicate]

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);

Why doesn't typeof work but isNaN works ?

Why doesn't this block work? I Used isNaN() and that works but not this, why? Javascript is behaving weirdly.
if( (typeof parseInt(returnedArr[count]) == 'number')
{
totalWorth= parseInt(totalWorth)+ parseInt(returnedArr[count]);
//document.write(returnedArr[count]);
}
Code:
function addWorth()
{
var table1= document.getElementById("tableNetWorths");
var rowCount1= table1.rows.length;
//var row1= table1.insertRow(rowCount1);
var arr= [];
for(var count = 0; count < rowCount1; count++)
{
arr.push(table1.rows[count].cells[1].innerHTML);
}
arr.shift();
return arr;
}
function showWorthSum()
{
var returnedArr= addWorth();
//returnedArr.push(addWorth());
totalWorth= 0;
var arrCount= returnedArr.length;
for(var count = 0; count < arrCount; count++)
{
if( (typeof parseInt(returnedArr[count]) == 'number')
{
totalWorth= parseInt(totalWorth)+ parseInt(returnedArr[count]);
//document.write(returnedArr[count]);
}
}
return parseInt(totalWorth);
}
If I use isNaN then that works but not this, why? My array looks like this:
{"100", "200", "asdasdadsa", "1"}
Because typeof NaN is "number":
console.log(typeof NaN);
NaN is a special value* of the number type, not its own type.
You haven't shown your code that uses isNaN, but note that if you pass a string into isNaN, it will be implicitly converted to number before being tested to see if the result of doing that is NaN (as though you had called Number(x) on it, or applied unary + or any of the non-addition math ops [-, *, /, etc.]).
Separately:
Beware that parseInt will happily parse a string that only starts with a number, ignoring the part after it that isn't numeric. For instance, parseInt("123abc") is 123.
Beware that when used without its second argument, parseInt will infer the number base (radix) from the string, so parseInt("0x10") is 16.
When dealing with user input, handling both of those situations intentionally is usually best:
function parseIntStrict(str) {
str = str.trim();
if (!/^\d+$/.test(str)) {
return NaN;
}
return parseInt(str, 10);
}
(Note that doesn't attempt to support scientific notation input; users don't usually input it.)
And for floating point:
function parseFloatStrict(str) {
str = str.trim();
if (!str) {
return NaN;
}
return +str;
}
(That does support scientific notation, but only as a byproduct of only checking for blank strings before handing off to built-in numeric conversion.)
Applying that to your code:
// I assume totalWorth is already a number
var entry = parseIntStrict(returnedArr[count]);
if (!isNaN(entry)) {
totalWorth = totalWorth + entry;
}
* Technically, per the IEEE-754 standard JavaScript uses, NaN is any of a range of values that all mean "not a number."
This is because the values in the array that you consider to be numbers are actually strings. For example, 100 is a number, but '100' is a string. typeof 123 will return 'number', but typeof '123' will return 'string'.
This means that all the values in your array are of type string and your code will not enter the if statement, if you use that approach.
However, since isNaN checks if an element in not a number, your code will work with that.

Comparing 1.3.52 and 1.3.54 as strings and as numbers

I am wondering why the following works:
oldversion = "1.3.52";
newversion = "1.3.54";
if (newversion > oldversion) {
console.log('test');
}
but this does not:
if (1.3.54 > 1.3.52) {
console.log('test');
}
I know that the last example won't work because they are not actual numbers. But I am trying to find out what JavaScript is doing when it encounters a string with a number in it.
This is what I found on W3Schools' JavaScript Comparison and Logical Operators page:
When comparing a string with a number, JavaScript will convert the
string to a number when doing the comparison.
So how come it converts the string to a number and suddenly I am not getting an Uncaught SyntaxError: Unexpected number anymore?
You could use a function which iterates the segments.
function checkVersion(a, b) {
var aa = a.split('.').map(Number),
bb = b.split('.').map(Number),
i,
r = 0,
l = Math.max(aa.length, bb.length);
for (i = 0; !r && i < l; i++) {
r = (aa[i] || 0) - (bb[i] || 0);
}
return r;
}
var oldversion = "1.3.52",
newversion = "1.3.54";
if (checkVersion(newversion, oldversion) > 0) {
console.log('test');
}
As mentioned in the comments, it's actually doing a string compare and not trying to turn anything into numbers.
You can verify this by trying:
var a = "a";
var b = "b";
console.log(a>b) // gives false
var a = "a";
var b = "b";
console.log(b>a) // gives true
As you say, when you compare a number and a string, the string gets transformed into a number. However, if the string contains an invalid number, the result will be NaN. This is funny due to the fact that:
NaN > 15 === false
NaN < 15 === false
So:
"1.3.52" > 1.4 === false
"1.3.52" < 1.4 === false
Obviously (and as you said in your post), comparing 1.3.52 with 1.3.54 will throw an exception because they're not valid numbers.
Why "1.3.52" is interpreted bigger than '1.12.10'?
Strings are compared using Unicode code point order. For example, "Banana" comes before "cherry". "9" is bigger than "80", but because "80" comes before "9" in Unicode order. Thus, "1.3.52" is interpreted as bigger than '1.12.10'.
An easy way to find out order between strings and not getting tricked is using sort. For instance, ["1.3.52", "1.12.10", "1.11.0.0.0"].sort()
#Nina's solution should be the accepted answer, as it will be easier to understand I think. But anyway..
function versionGreaterEqual(newversion, oldversion) {
var ov = oldversion.split('.').map(Number), //credit Nina :)
nv = newversion.split('.').map(Number);
return nv.reduce(function (a,b,i){
return a+=b>=ov[i];
},0)===nv.length;
}
console.log(versionGreaterEqual("1.3.54", "1.3.52")); //true
console.log(versionGreaterEqual("1.3.54", "1.13.52")); //false

javascript function not working as expected

I have the following code in an external javascript file. I am getting an error on this line below: guessNum = inGuess.parseInt();
firebug tells me the parseInt is not a function. I thought all things in js were basically objects (at least that is what I remember reading in W3School). I am sure this is something simple, I am just stuck. Any suggestions are welcome. Thanks
function inputNum()
{
/* initialize variables */
var inGuess = "";
var loopCt;
var guessResult = "";
var correctNum = 26;
var guessNum = 0;
for (loopCt=1;loopCt<11;loopCt++)
{
inGuess = prompt("Please enter your guess(enter -1 to exit) Do not press Enter","0");
if (inGuess == "-1") { break; }
if (inGuess==null || inGuess=="")
{
alert("Blanks are not allowed. To exit enter '-1'.");
}
else
{
guessNum = inGuess.parseInt();
if (inGuess == "26")
{
alert("Congratulations, you guess correctly!");
guessResult="Correct!";
}
else
if (guessNum < correctNum)
{
guessResult="Too low";
}
else
{
guessResult="Too high";
}
document.getElementById('emp'+loopCt).innerHTML=inGuess;
document.getElementById('ct'+loopCt).innerHTML=guessResult;
}
}
}
parseInt is a global function. You are trying to access it off of a string object, where it doesn't exist.
guessNum = parseInt(inGuess, 10); // Tell it what base to use. Protect against 08 being interpretued as octal.
That would be the correct way to handle this.
parseInt Mozilla Developer Network Docs
Footnote - parseInt can return NaN which when compared with typeof actually returns number
parseInt is a method on window, not on a string. You want
guessNum = parseInt(inGuess, 10);
The second argument insures that your code will treat the first argument as a base-10 number, meaning it will correctly parse "010" as 10 and reject "0x10" instead of parsing it as 16.
I thought all things in js were basically objects
They are objects, but that doesn't mean that all objects have the same set of methods defined on them.
If you do want to use it like that for whatever exotic reason, you can define prototype on the String object:
String.prototype.parseInt = function() {
return parseInt(this,10);
}
var inGuess = "26";
alert(inGuess.parseInt());
Your syntax isn't quite right... From the console:
> x = parseInt("2", 10)
2
Also, something to keep in mind, which come from the docs...
If the input string begins with "0", radix is eight (octal) or 10 (decimal). Exactly which radix is chosen is implementation-dependent. ECMAScript 5 specifies that 10 (decimal) is used, but not all browsers support this yet. For this reason always specify a radix when using parseInt.
parseInt() Documentation
inGuess is a string and string does not have parseInt function. parseInt is a global function.
do this:
guessNum = parseInt(inGuess);

jQuery Validation, Numeric Value Only

I'm trying to validate a form input value. The function below states is the value of the input is a number below 150, show error. Works as it should. However, I want to add to it. If the value contains ANYTHING other than a numeric value AND/OR is a value under 150, show error...
How can I modify?
if ($('.billboard-height').val() < 150) {
$('.sb-billboardalert').fadeIn(600);
}
Since your more thorough validation should be on the server-side anyway, you could just use parseInt or parseFloat depending on what sort of value you are expecting. Then check if the result is actually a number and that it also meets your constraints:
var number = parseFloat($('.billboard-height').val()); // or parseInt depending on expected input
if (isNaN(number) || number < 150) {
$('.sb-billboardalert').fadeIn(600);
}
EDIT:
Based on your comments, you are entering regex land. I gather you only ever want a natural number (and the way parseInt/parseFloat ignores trailing non-numeric characters like px, em, etc. is not ok). How about:
var val = $('.billboard-height').val();
var number = parseInt(val, 10);
if ( ! val.match(/^[0-9]{3,4}$/) || number < 150) {
$('.sb-billboardalert').fadeIn(600);
}
This should only allow natural numbers 150-9999.
I would suggest using regexes:
var intRegex = /^\d+$/;
var floatRegex = /^((\d+(\.\d *)?)|((\d*\.)?\d+))$/;
var str = $('#myTextBox').val();
if(intRegex.test(str) || floatRegex.test(str)) {
alert('I am a number');
...
}
Or with a single regex as per #Platinum Azure's suggestion:
var numberRegex = /^[+-]?\d+(\.\d+)?([eE][+-]?\d+)?$/;
var str = $('#myTextBox').val();
if(numberRegex.test(str)) {
alert('I am a number');
...
}
ref: checking if number entered is a digit in jquery
Don't forget the radix parameter in parseInt():
if (parseInt($('.billboard-height').val(), 10) < 150) {
It's probably faster than using a regex. Regular expressions are not known for being fast, but they are very powerful. It might be overkill for this scenario.
You can try out HTML5's built in form validation:
<input type="number" min="150">
browser support is still pretty shakey though
Any value from an input or select will be a string in javascript. You need to use parseInt() to use operators like > or <. == can be used if you use it to compare to a string like if ($('.billboard-height').val() == "150")
Try parseInt and isNaN functions for check if value is number and less than 150:
var intVal = parseInt($('.billboard-height').val());
if(!isNaN(intVal)){ //not Number
if (parseInt($('.billboard-height').val()) < 150) { //not less than 150
$('.sb-billboardalert').fadeIn(600);
}
}
If you need to support floating point numbers, you can check if a variable is valid using:
function isNumber (n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
var val = $('.billboard-height').val();
if (isNumber(val) && parseFloat(val) < 150) {
$('.sb-billboardalert').fadeIn(600);
}
If you only need to support integers, use parseInt(n, 10), where 10 is the base to convert the string to.
var val = parseInt($('.billboard-height').val(), 10);
if (val && val < 150) {
$('.sb-billboardalert').fadeIn(600);
}
// Displays an alert if s contains a non-numeric character.
function alertForNonNumeric(s) {
var rgx = /[^0-9]/;
if (s.search(rgx) !== -1) {
alert("Input contains non-numeric characters!");
}
}
JS Fiddle here
NOTE: If you want to check for negative ints as well, you can add a minus sign to the regex:
function alertForNonNumeric(s) {
var rgx = /[^0-9-]/;
if (s.search(rgx) !== -1) {
alert(s + " contains non-numeric characters!");
}
}
I use this solution, I find it quite ellegant - no alerts, user is effectively unable to enter non numeric characters.
This is jQuery example:
function digitsOnly(){
// extract only numbers from input
var num_val = $('#only_numbers').val().match(/\d+/);
$('#only_numbers').val(num_val);
}
Your html:
<input type="text" name="only_numbers" id="only_numbers" on oninput="digitsOnly();"/>

Categories