Reputation: 944
We know that by default, the 'obj' below is string. Without using 'parseInt', how does JavaScript compare it with a number?
obj = document.frm.weight.value;
if( obj < 0 || obj > 5 ){
alert("Enter valid range!");
return false;
}
Upvotes: 0
Views: 243
Reputation: 1032
Well, as an EMCAScript implementation, Javascript will follow the Abstract Relational Comparison Algorithm as defined in the 11.8.5 section of the Ecma-262.
Firstly Javascript will apply to both operands the internal operator ToPrimitive
, which must return a primitive value (undefined, boolean, string, null or number) based on the arguments passed to it. If a primitive value is passed to ToPrimitive
the return value is the argument value passed to the operator, if it's an Object an internal method that all Objects in Javascript implements is called, it's the [[DefaultValue]].
This method is responsible for returning a primitive type that an Object represents. Depending on the type of code this method may call either toString
or valueOf
methods of the Object.
For instance:
var x = {valueOf: function() { return 3; }};
console.log(x > 2); // true
console.log(x < 1); // false
console.log(x == 3); // true
How does the Javascript decide which method it should call? Well, the ToPrimitive
operator may recieve an optional parameter, it's used to give preference to a specific type, e.g. Number
or String
.
If Number
is passed, the valueOf
method will be called first, if that method doesn't exist in the Object or doesn't return a primitive type, toString
is called then. If String
is passed, the reverse occurs: toString
is called first, if it neither exists in the Object nor returns a primitive value, valueOf
is called.
This is why, in the above snippet, I can compare an Object and a primitive type freely. It's really important to understand when dealing with comparison.
After that, if both operands are Strings
Javascript will follow some interesting and specific algorithm related to Unicode Standard, checking for code points values. Otherwise, Javascript will cast both operands to Number
and their mathematical value are compared. Note that if one of them is NaN the comparison evaluates to undefined, which would be false in an if
statement.
Some examples:
// true => ToNumber(true) > ToNumber(false)
console.log(true > false);
// true => ToNumber("5") < ToNumber(10)
console.log("5" < 10);
// false ToNumber(ToPrimitive(obj, Number)) == ToNumber(10)
console.log(({valueOf: function() { return 10}}) > 10);
// false, it's not related to the length of the strings,
// the code point value of each char is used to evaluate the comparison
console.log('Hello worlds' > 'hello');
Hope it helps to clarify something.
Upvotes: 3
Reputation: 324750
The string will be cast to a number using arbitrary rules. Typically you'll see rules like this:
0x
, treat it as a hexadecimal number.0
, treat it as an octal number. (not in all browsers)This means in particular that input like "09" could be confusing to the browser and it may be interpreted as 9
or 0
(because nine is not a valid octal digit).
In general, when comparing a string to a number, you should always manually call parseInt
with a radix argument of 10
. That way, there are no surprises.
Upvotes: 0
Reputation: 8609
If one of the operands of <
or >
is number, the other one will be casted to a number.
alert("3" > 3); // false
alert("3.5" > 3); // true
EDIT and further explanation:
If it is not possible to cast the other parameter into a number, it is casted into the special value called NaN
- the abbreviation stands for "Not a Number". The NaN
value has a special property that it is absolutely incomparable - all relation operators like <
, >
and =
will return false
if one of the arguments is NaN
.
alert("" > 3); // false
alert("3.5?" > 3); // false
alert({} > 3); // false
Also, note that in the second line, if we used
alert(parseInt("3.5?") > 3);
it would alert true
, because parseInt
reads "3.5"
from the string "3.5?"
, then stops reading at "?"
and thus evaluates to 3.5
. However,
alert("3.5?" > 3);
returns false
because the cast from string
to number
is not as benevolent as parseInt
. As "3.5"
indeed isn't a number, it is casted to NaN
.
Upvotes: 2