Question

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;
}
Was it helpful?

Solution

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.

OTHER TIPS

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.

The string will be cast to a number using arbitrary rules. Typically you'll see rules like this:

  • If the string starts with 0x, treat it as a hexadecimal number.
  • If the string starts with 0, treat it as an octal number. (not in all browsers)
  • Otherwise, treat it as decimal.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top