ECMAScript says that a piece of data can be converted to each of the obvious primitive types: Boolean, Number and String. If the piece of data is an Object, then the valueOf() method will be used to return a Number, and the toString() method will be used to return a String. If the piece of data isn't an Object, then the JavaScript interpreter does the job itself, internally. These conversions are mostly intuitive—for example, the following values all become false
when converted to a Boolean value: undefined
, null
, false
, 0
, NaN
, and ""
(the
empty
string).
Converting a String to a Number is tricky. Either the String looks like a number or it doesn't. The latter case produces NaN, but the former case isn't simple. Because the Number type has a limit to the number of digits it can store, there is a special piece of agony the interpreter must go through to store the closest possible value to the number represented in the String. This is the business of rounding, and applies in the reverse as well: converting a Number to a String. This can be particularly irritating because some JavaScript implementations can cause 6 / 2 to equal 2.99999999 instead of 3—although you usually have to pick more obscure number combinations to see this happening.
The URL http://developer.netscape.com/library/examples/JavaScript/rounding.html
contains a JavaScript function that will round a variable that otherwise isn't rounding well. ECMAScript-compliant JavaScript will correctly round. This example reveals at least one problem in most Netscape browser versions; Microsoft browsers generally round better.
var x = 0.03;
var y = 0.09+0.01;
var z = 1.23456789012345678;
document.write(x + ' ' + y + ' ' + z);
The moral of this example is: don't rely on the built-in support for number rounding if you want to display highly accurate numbers. If you have a JavaScript implementation that isn't rounding well, or if you are doing complex mathematics, then the ultra-safe way to compare Numbers is to use this old trick:
var tiny = 1e-10;
if ( Math.abs(value – 1.2345) < tiny) ) // Math.abs() removes the sign of a Number
{
document.write("so close it's the same as 1.2345.");
}
else
{
document.write('some number other than 1.2345.');
}
There are a few other subtle conversions that are generally invisible to the script writer—see Reference Sections A and C.
The ability to convert to primitive types freely means that the following examples contain no ambiguities:
var u = String(23); // "23"
var v = Number("44.55"); // 44.55
var w = +("0xFE99"); // 65177
var x = "23.45" – 10; // 13.45 – minus only accepts Number types
var y = ( "fred" && 23 ); // true
var z = ( "0xFF" & 0xF0 ); // 0xF = 15