Checking value of HTML input issues - javascript

I have this HTML:
<input type="number" id="num">
<input type="submit" onclick="test()">
and this script:
function test() {
var num = document.getElementById("num").value;
alert(num === 1);
so why do I get false when I enter 1 as my input?
If I try alert(num - 1 === 0); instead of alert(num === 1); I get true. Why does this happen?

The values of form controls are always strings (type="number" just asks the browser to enforce that the string contains a number). You can convert it to a number with +, parseInt, or parseFloat. You could also compare to "1" instead of 1.
If you subtract a number from a string, JavaScript will convert the string to a number before performing the subtraction, and then the result will evaluate as a number.

Consider changing it to a string.
function test() {
var num = document.getElementById("num").value;
alert(num === "1");
The === operator is much stricter and requires the compared values to be of both equal value and type. In this case you are comparing a string to a number.

Quentin's answer is correct, but just to add to it:
You can check if it is 1 using lazy equals (I.e. no type checking.) num == 1
Or, just compare against a string: num === "1"

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

JavaScript: Why []+(-~{}-~{}-~{}-~{})+(-~{}-~{}); returns "42"

Saw this in my newsletter. Tested on Chrome and Firefox. I still can't figured it out.
[]+(-~{}-~{}-~{}-~{})+(-~{}-~{}); //=> "42"
Evaluating:
~{}
is evaluated using the internal function:
~ToInt32({})
which gives -1.
Ref ECMA spec - http://www.ecma-international.org/ecma-262/5.1/#sec-9.5
and this explanation - http://jibbering.com/faq/notes/type-conversion/#tcToInt32
Therefore, in this case
(-~{}-~{}) == 2
(-~{}-~{}-~{}-~{}) == 4
As you have []+ in the start of expression, javascript use plus operands like string. So you have "" + "4" + "2" = "42"
The ~ operator is a Bitwise NOT operator. It returns the "1's complement" of a number. Because of that {} is converted into a number, resulting in NaN. The same would happen with +{} == NaN. The bitwise not of ~NaN == -1. So:
(-~{}-~{}-~{}-~{}) == 4 & (-~{}-~{}) == 2
The DefaultValue for an empty array is an empty string. For example []==[]+[] && []+[]==''
From that, the full parsing is:
[]+ /*converted to ''+*/ (-~{}-~{}-~{}-~{}) /*Equals numeric 4, but concatenated as a string to become '4'*/ + (-~{}-~{}) /*Equals numeric 2, but concatenated as a string to become '2'*/ and the end result is actually '42'.
You can validate this via typeof([]+(-~{}-~{}-~{}-~{})+(-~{}-~{})) === 'string'

Having trouble understanding function involving number addition

function NumberAddition(str) {
var nstr = str.match(/[0-9]+/g);
var total = 0;
if (nstr !== null)
for (var i = 0; i < nstr.length; i++) {
total += nstr[i]*1;
}
// code goes here
return total;
}
I was looking at answers in coderbyte.com and this was one of them. My question is about the total += nstr[i]*1 section. if I remove the *1 the answer is concatenated to "2344". However the answer should be 23+4+4=31. why is this?
The *1 forces the string in nstr[i] to be converted to a number. Another way to do that would be
total += +nstr[i];
The * (multiplication) operator is only meaningful for numbers, and the language definition stipulates that when its arguments are not numbers, they should be converted. Of course, if nstr[i] isn't really a number (unlikely in your case, if not impossible) then the result would be a NaN value. Similarly, the unary + operator also forces its operand to be converted to a number.
Multiplying a value by 1 is a way to ensure that it gets converted to a number if it isn't. When you add two things in JavaScript, if either is a string then the operation gets evaluated as string concatenation, not addition. Since the values in nstr were the result of a regular expression match, they are string values, not number values.
You can multiply a value by 1 to make sure that it is treated as a number. The canonical JavaScript way to do this is to use the unary + operator (total += +(nstr[i]);).
> "1"+1
"11"
> 1+"1"
"11"
> 1+1
2
> ("1"*1)+1
2
> (+"1")+1
2

parseInt doesn't work

in my current source code textbox value is 1.
when I try alert(isNaN(obj.text()) it returns false that is expected but after parseInt when I write alert(a); it returns NaN
minus.click(function () {
var a = 1; if (!isNaN(obj.text())) a = parseInt(obj.text());
if (a > 1) a -= 1; obj.text(a);
});
what is the problem?
Edit: this is the full code:
<input type="text" class="basket-txt" value="1" />
jQuery.fn.basket = function (options) {
var defaults = {
}
options = jQuery.extend(defaults, options);
this.each(function () {
var $this = $(this);
$this.height(32).css({ 'line-height': '32px', 'font-weight': 'bold', 'width':'40px', 'text-align':'center', });
var tbl = $('<table border="0" style="border-spacing:0px;float:left;">').appendTo($this.parent());
var tr1 = $('<tr>').appendTo(tbl);
var plus = $('<div class="basket-plus">');
$('<td>').append(plus).appendTo(tr1);
$('<td>').append($this).appendTo(tr1);
var minus = $('<div class="basket-minus">');
$('<td>').append(minus).appendTo(tr1);
var tr2 = $('<tr>').appendTo(tbl);
$('<td>').appendTo(tr2);
$('<td>').appendTo(tr2).append($('<div>').addClass('add-to-basket'));
$('<td>').appendTo(tr2);
$this.keypress(function (e) { if (e.which < 48 || e.which > 57) e.preventDefault(); });
minus.click(function () {
var a = 1; if (!isNaN($this.text())) a = parseInt($this.text());
if (a > 1) a -= 1; $this.text(a);
});
plus.click(function () {
var a = 1; if (!isNaN($this.text())) a = parseInt($this.text());
if (a < 1000000) a += 1; $this.text(a);
});
});
}
actually I knew I could correct the code and it would work my concern was to understand why isNaN returns false but parseInt returns NaN
The jQuery text() method will take all the descendent text nodes of an element and combine them into a single string.
An input element can't have descendant nodes of any kind. Its current value is exposed via the value property, which you can read with the val() method in jQuery.
You shouldn't use parseInt without a radix, especially with free form input. You might get octal or hex data instead of a decimal.
parseInt($this.val(), 10)
You get the value of an <input> with .val(), not .text().
The isNaN() function returns false for isNaN(""). Why? Because when "" (the empty string) is converted to a number, it's 0. Pass a non-number to isNaN() and the first thing it does is coerce the value into a number.
It's kind-of pointless to try isNaN() before parseInt() anyway, since parseInt() will tell you when it can't parse a nice-looking integer. Note however that parseInt() doesn't care if there's garbage at the end of the input.
If you want to convert a string to a number when it's a valid string representation of a number, and NaN when it isn't, you can use
var myNumber = +myString;
That'll accept numbers with fractional parts and exponents too, so you'd have to either truncate that to just an integer or check to see if it is one:
var myNumber = +myString;
if (isNaN(myNumber))
// not a valid number
else if (myNumber !== Math.floor(myNumber))
// not an integer
else
// yaay!
minus.click(function () {
// let's parse the integer first
var num = parseInt( obj.val(), 10 );
// then later, we can check if it's NaN
if ( !isNaN(num) && num > 1 ) {
num -= 1;
obj.val(num);
}
});
actually I knew I could correct the code and it would work my concern was
to understand why isNaN returns false but parseInt returns NaN
isNaN doesn't work the way it should. There is type coercion going on.
isNaN will convert the value to a number first. An empty string will be converted to a 0
Number("") === 0; // true
0 is obviously not NaN, so it returns false.
parseInt doesn't do type coercion, it parses the value differently.
Check this question and this other question for reference.
parseInt returns NaN when the first non-whitespace character cannot be converted to a number.

Checking only the integer values through Regex

My Code:
I tried the following code
<SCRIPT type="text/javascript">
var num = "10";
var expRegex = /^\d+$/;
if(expRegex.test(num))
{
alert('Integer');
}
else
{
alert('Not an Integer');
}
</SCRIPT>
I am getting the result as Integer. Actually I declared the num varibale with double quotes. Obviously it is considered as a string. Actually I need to get the result as Not an Integer. How to change the RegEx so that I can get the expected result.
In this case, it should give the result as Not an Integer. But I am getting as Integer.
if(typeof num === "number" &&
Math.floor(num) === num)
alert('Integer');
else
alert('Not an Integer');
Regular expressions are there to work on strings. So if you tried it with something else than a string the string would either be converted or you would get an error. And yours returns true, because obviously the string only contains digit characters (and that is what you are checking for).
Use the typeof operator instead. But JavaScript doesn't have dedicated types for int and float. So you have to do the integer check yourself. If floor doesn't change the value, then you have an integer.
There is one more caveat. Infinity is a number and calling Math.floor() on it will result in Infinity again, so you get a false positive there. You can change that like this:
if(typeof num === "number" &&
isFinite(num) &&
Math.floor(num) === num)
...
Seeing your regex you might want to accept only positive integers:
if(typeof num === "number" &&
isFinite(num) &&
Math.floor(Math.abs(num)) === num)
...
RegExp is for strings. You can check for typeof num == 'number' but you will need to perform multiple checks for floats etc. You can also use a small bitwise operator to check for integers:
function isInt(num) {
num = Math.abs(num); // if you want to allow negative (thx buettner)
return num >>> 0 == num;
}
isInt(10.1) // false
isInt("10") // false
isInt(10) // true
I think it's easier to use isNaN().
if(!isNaN(num))
{
alert('Integer !');
}
else
{
alert('Not an Integer !');
}
Léon

Categories