Introduction

Javascript (ECMAScript) is a loosely typed language. That does not mean
that it has no data types just that the value of a variable or a Javascript
object property does not need to have a particular type of value assigned
to it, or that it should always hold the same type of value. Javascript
also freely type-converts values into a type suitable for (or required by)
the context of their use.

Javascript being loosely typed and willing to type-convert still does not
save the programmer from needing to think about the actual type of values
that they are dealing with. A very common error in browser scripting, for
example, is to read the value property of a form control into which the
user is expected to type a number and then add that value to another
number. Because the value properties of form controls are strings (even if
the character sequence they contain represents a number) the attempt to
add that string to a value, even if that value happens to be a number,
results in the second value being type-converted into a string and
concatenated to the end of the first string value from the from control.

That problem arises from the dual nature of the + operator
used for both numeric addition and string concatenation. With which the
nature of the operation performed is determined by the context, where
only if both operands are numbers to start with will the +
operator perform addition. Otherwise it converts all of its operands to
strings and does concatenation.

The following discussion is illustrated with Javascript generated tables
of values resulting from the conversion operations. The headers of those
tables display the values as represented in the Javascript source code
used rather than their internal representation. So, for example
123e-2 as a number was the character sequence typed into
the source code, the interpreter reads that and generates the
number value 1.23 from it for internal use. The various values used for
the tests have been chosen to illustrate aspects of type
converting, those aspects may not apply to all of the tables presented.
However, all of the test values are included in all of the tables (except
where no type converting occurs) for full comparison. The bodies of the
tables list the results of the various type conversion operations.

If you are accepting/using this page's CSS style suggestions the type
of the values at various stages is illustrated by the colour of the text
used. The following key shows those type/colour relationships, they are
derived from the string values returned by the typeof
operator (which returns "object"
for the null type when in reality null is
distinct from objects).

Key

string

number

boolean

object

function

null

undefined

The boolean values of results also have a coloured background to highlight
true or false.

Converting to Boolean

When evaluating the expression of an if statement the Javascript
interpreter will type-convert the result of that expression to boolean
in order to make its decision. Also various operators internally
type-convert their operands to boolean in order to determine what
action to take. These include the logical operators like AND
(&&), OR (||) and NOT (!). The NOT
operator type-converts its operand to boolean and if that value is
boolean true it returns false and if false it returns true. As the
result of a NOT operation is a boolean value that is the inverse of
the type-converted true-ness of its operand, two NOT operations
together will return a boolean value that is equivalent to the result
of type-converting the operand to boolean:-

var boolValue = !!x;

That technique has been used to generate the following tables.

An alternative method of generating a boolean value that represents
the type-converted true-ness of a value is to pass that value to
the Boolean constructor called as a function:-

var boolValue = Boolean(x);

Double NOT (!!col) : Numeric Values.

-1.6

-0

+0

1

1.6

8

16

16.8

123e-2

-Infinity

+Infinity

NaN

!!col

true

false

false

true

true

true

true

true

true

true

true

false

When numbers are converted to boolean, zero becomes false and all other
numbers are true. With the excepting of the special numeric value
NaN (Not a Number) which is used when another type is
converted to a number but that conversion does not result in a
meaningful number. NaN is always false. The values of
positive and negative infinity, while not finite numbers, are non-zero
numeric values and always type-convert to boolean true.

Double NOT (!!col) : String Values.

""(emptystring)

"-1.6"

"0"

"1"

"1.6"

"8"

"16"

"16.8"

"123e-2"

"010"(Octal)

"0x10"(Hex)

"0xFF"(Hex)

"-010"

"-0x10"

"xx"

!!col

false

true

true

true

true

true

true

true

true

true

true

true

true

true

true

Type conversion rules are even simpler for string to boolean conversion
as all non-empty strings always become true and empty strings become
false.

Double NOT (!!col) : Other Values

undefined

null

true

false

new Object()

function(){ return;}

!!col

false

false

true

false

true

true

For the other types, undefined and null are
converted to false, boolean values are not converted and objects and
functions are always true.

This is the most valuable aspect of type-converting to boolean as it
allows a script to distinguish between properties in an environment
that may be undefined or may refer to an object. Treating an undefined
(or null) value as if it was an object will produce errors. So when
there is a doubt (as there usually is where web browsers are concerned)
then code can avoid generating errors by wrapping the code that wants
to access an object in an if test. Supplying the suspect
reference to the object as the expression. The expression will be type
converted to boolean and result in false if the object
does not exist and true if it does.

Converting to String

As mentioned above, type conversion to a string most often results
from the action of the + operator whenever one of its operators in
not a number. The easiest way of getting the string that results
from type-conversion is to concatenate a value to an empty string.
That technique has been used to generate the following tables.

An alternative method of converting a value into a string is to
pass it as an argument to the String constructor
called as a function:-

var stringValue = String(x);

type-convert to string ("" + col) : Numeric Values.

-1.6

-0

+0

1

1.6

8

16

16.8

123e-2

-Infinity

+Infinity

NaN

"" + col

-1.6

0

0

1

1.6

8

16

16.8

1.23

-Infinity

Infinity

NaN

Notice that the number generated from the source code 123e-2
has resulted in the string "1.23" because that is
the string representation of the internal number created from the source
code. However, Javascript's internal number representations take the form
of IEEE double precision floating point numbers and that means that they
cannot represent all numbers with precision. The results of mathematical
operations may only produce close approximations and when they are
converted to strings the string represents the approximation and may be
unexpected and undesirable. It is often necessary to use custom functions
to generate string representations of numbers in an acceptable format,
the type-conversion mechanism is rarely suited to generating numeric output
intended for presentation.

type-convert to string ("" + col) : Other Values.

undefined

null

true

false

new Object()

function(){ return;}

"" + col

undefined

null

true

false

[object Object]

function(){
return;
}

When objects or functions are type-converted to strings their
toString method is called. These default to
Object.prototype.toString and
Function.prototype.toString but may be overloaded
with a function assigned to a "toString" property of
the object/function. Type-converting a function to a string does
not necessarily result in the function's source code. The behaviour
of Function.prototype.toString is implementation
depended and varies quite a lot, as do the results from
"host objects" and methods (the objects and methods
provided by the environment, such as DOM elements).

Converting to Number

Converting values to numbers, especially strings to numbers, is an
extremely common requirement and many methods can be used. Any
mathematical operator except the concatenation/addition operator
will force type-conversion. So conversion of a string to a number
might entail performing a mathematical operation on the string
representation of the number that would not affect the resulting
number, such as subtracting zero or multiplying by one.

However, the unary + operator also type-converts its
operand to a number and because it does not do any additional
mathematical operations it is the fastest method for type-converting
a string into a number.

Incidentally, the unary - (minus) operator also
type-converts its operand (if necessary) in addition to
subsequently negating its value.

While unary + is the fastest method for converting a
string to a number a final method is available that uses the
Javascript type-conversion algorithms. The Number
constructor can be called with the string value as its argument
and its return value is a number representing the result of the
type-conversion.

var numValue = Number(stringValue);

The Number constructor is the slowest of the type-converting
methods but when speed is not an overriding consideration its
use does produce the clearest source code.

The following tables show the results of type-conversion to a number using
the unary + operator. Though all of the preceding
alternative method produce the same results as they all use exactly the
same algorithm to do the conversion.

type-convert to number (+col) : String Values.

""(emptystring)

"-1.6"

"0"

"1"

"1.6"

"8"

"16"

"16.8"

"123e-2"

"010"(Octal)

"0x10"(Hex)

"0xFF"(Hex)

"-010"

"-0x10"

"xx"

+col

0

-1.6

0

1

1.6

8

16

16.8

1.23

10

16

255

-10

NaN

NaN

The important considerations when converting strings to numbers with
the type-converting methods is the results from strings that do not
represent numbers. The empty string is converted into the number zero,
depending on the application this can be harmless or disastrous, but
it is important to be aware that it is going to happen. In other
contexts strings that follow the Javascript format for octal number
(leading zero) can be problematic but type conversion treats them
as base 10 anyway. However, strings that follow the format for
hexadecimal numbers (leading 0x or 0X)
are read as hexadecimal. Strings that cannot be read as a number
type-convert to NaN, which can be tested for with
the isNaN function. Strings representing numbers in an
exponential format ("123e-2") are understood
along with leading minus signs.

type-convert to number (+col) : Other Values.

undefined

null

true

false

new Object()

function(){ return;}

+col

NaN

0

1

0

NaN

NaN

Objects and functions always type-convert to NaN numbers, as do
undefined values but it is worth noting that null
type-converts to zero. Probably because it is being type-converted to boolean
first and then to number and, as is clear from the boolean results
above, null would become boolean false which
would then become numeric zero. There is almost no need to type convert
these types of values into numbers. How they convert is only really
relevant to a consideration of the accidental result of converting a
value that is expected to be a string but actually turns out to be one
of these (and/or performing an mathematical operation with one of these as an operand).

Parsing to Number

An alternative method of converting a string into a number is to use
one of the global functions designed to parse a string and return a
number. The parseFloat function accepts a string argument
and returns a floating point number resulting from parsing that string.
Non-string arguments are first type-converted to a string as described
above.

The string parsing functions read the string character by character until
they encounter a character that cannot be part of the number, at which
point they stop and return a number based on the characters that they
have seen that can be part of the number. This feature of their action
can be usefully exploited, for example, given a string representing a
CSS length value such as "34.5em"parseFloat would be able to ignore the "em"
because those characters cannot be combined with the preceding set to
produce a valid number. The returned number would be 34.5, the numeric
part of the CSS string stripped of its units.

parseFloat

parseFloat(col) : String Values.

""(emptystring)

"-1.6"

"0"

"1"

"1.6"

"8"

"16"

"16.8"

"123e-2"

"010"(Octal)

"0x10"(Hex)

"0xFF"(Hex)

"-010"

"-0x10"

"xx"

parseFloat(col)

NaN

-1.6

0

1

1.6

8

16

16.8

1.23

10

0

0

-10

0

NaN

With parseFloat empty strings return NaN
along with strings that cannot be subject to numeric interpretation.
The exponential format is understood and the leading zero in the
octal format does not hinder the string's interpretation as a
decimal number. Hexadecimal strings are interpreted as the number
zero because the following "x" cannot be
interpreted as part of a number so parsing stops after the leading zero.

parseFloat(col) : Other Values.

undefined

null

true

false

new Object()

function(){ return;}

parseFloat(col)

NaN

NaN

NaN

NaN

NaN

NaN

Non-string values are first converted into a string that is employed
by parseFloat. As that type-conversion to a string would
not normally result in a string that could be interpreted as a number
the result is NaN. Objects and functions may have custom
toString methods that may return strings that could be
interpreted as numbers but that would be an unusual requirement.

parseInt

The parseInt function works in a similar way to
parseFloat except that it is trying to interpret its
string argument into an integer and as a result recognises fewer
character as possible candidates to be part of that number.

parseInt is occasionally used as a means of turning a
floating point number into an integer. It is very ill suited to that
task because if its argument is of numeric type it will first be
converted into a string and then parsed as a number, very inefficient.
This can produce very wrong results with numbers such as
2e-200, for which the next smaller integer is zero, but
with which parseInt returns 2. Also, because
of the number format used by javascript, numbers are often represented
by near approximations. So, for example, 1/2 + 1/3 + 1/6 =
0.9999999999999999, which isn't quite one and parseInt would return
zero if asked to act on the result of the operation.

For rounding
numbers to integers one of Math.round, Math.ceil
and Math.floor are preferable, and for a desired result
that can be expressed as a 32 bit signed integer the bitwise operation
described below might also suit.

parseInt(col) : Numeric Values.

-1.6

-0

+0

1

1.6

8

16

16.8

123e-2

-Infinity

+Infinity

NaN

parseInt(col)

-1

0

0

1

1

8

16

16

1

NaN

NaN

NaN

When it is acting on number the effect of the initial type-conversion
of the argument to a string is evident in the results. Note that the
value 123e-2 is internally the number 1.23
and that type converts into the string "1.23",
so that entry in the table above might look odd but it is correct.

parseInt(col) : String Values.

""(emptystring)

"-1.6"

"0"

"1"

"1.6"

"8"

"16"

"16.8"

"123e-2"

"010"(Octal)

"0x10"(Hex)

"0xFF"(Hex)

"-010"

"-0x10"

"xx"

parseInt(col)

NaN

-1

0

1

1

8

16

16

123

8

16

255

-8

-16

NaN

Strings in octal and hexadecimal number formats do represent integers
and parseInt is capable of interpreting them in accordance
with the rules for Javascript source code, even when they have leading
minus signs.

parseInt(col) : Other Values.

undefined

null

true

false

new Object()

function(){ return;}

parseInt(col)

NaN

NaN

NaN

NaN

NaN

NaN

As parseInt type-converts its non-string arguments to
strings it always produces the same results for boolean,
null, undefined, object and function
arguments as parseFloat (assuming objects and functions
do not have custom toString methods).

parseInt with a radix argument

It is rarely desirable to allow parseInt to deduce the
base in which the number is represented from the string as leading zeros are
rarely intended to indicate data in octal format (particularly with
user input). To deal with this problem parseInt recognises
a second, radix, argument that can be used to specify the base in which the
string is to be interpreted. Specifying a second argument of 10 causes
parseInt to interpret the strings as only base 10.

parseInt(col, 10) : String Values.

""(emptystring)

"-1.6"

"0"

"1"

"1.6"

"8"

"16"

"16.8"

"123e-2"

"010"(Octal)

"0x10"(Hex)

"0xFF"(Hex)

"-010"

"-0x10"

"xx"

parseInt(col, 10)

NaN

-1

0

1

1

8

16

16

123

10

0

0

-10

0

NaN

The string in octal format is now interpreted as base 10 and the
hexadecimal strings can now only be zero as parsing has to stop
when the "x" is encountered.

Number bases 2 to 36 can be used with parseInt. The
following is base 16.

parseInt(col, 16) : String Values.

""(emptystring)

"-1.6"

"0"

"1"

"1.6"

"8"

"16"

"16.8"

"123e-2"

"010"(Octal)

"0x10"(Hex)

"0xFF"(Hex)

"-010"

"-0x10"

"xx"

parseInt(col, 16)

NaN

-1

0

1

1

8

22

22

4670

16

16

255

-16

-16

NaN

The hexadecimal 0x format is recognised again with the
base 16 interpretation.

Finally base 3:-

parseInt(col, 3) : Numeric Values.

-1.6

-0

+0

1

1.6

8

16

16.8

123e-2

-Infinity

+Infinity

NaN

parseInt(col, 3)

-1

0

0

1

1

NaN

1

1

1

NaN

NaN

NaN

The consequences of the type-converting of numeric arguments to
strings is evident again. The number 8 is coming out
as NaN because the "8" character
cannot be interpreted as base 3, leaving an empty sequence of
acceptable characters and producing the same result as an empty string.

parseInt(col, 3) : String Values.

""(emptystring)

"-1.6"

"0"

"1"

"1.6"

"8"

"16"

"16.8"

"123e-2"

"010"(Octal)

"0x10"(Hex)

"0xFF"(Hex)

"-010"

"-0x10"

"xx"

parseInt(col, 3)

NaN

-1

0

1

1

NaN

1

1

5

3

0

0

-3

0

NaN

ToInt32

ToInt32 is an internal function only available to the
Javascript implementation and cannot be called directly from scripts
in the way that parseInt can. It is a bit unusual to mention it in
connection with converting Javascript values to numbers but it can
be used in a limited set of circumstances. The bitwise operators such
as bitwise OR (|) and bitwise AND (&) operate on
numbers so they type-convert their operands to numbers. However, they
also only operate on 32 bit signed integers so given the (possibly
type-converted) numeric value they call the internalToInt32 function with that number as its argument and
use the returned value as their operand. That returned value is always
a 32 bit signed integer.

The effect can be like parseInt combined with type-converting
to numbers. While the result is limited in range to 32 bits, it is
always numeric and never NaN, or ±
Infinity.

As with using mathematical operators in operations that have no effect on
the value of any resulting number it is possible to perform a bitwise
operation that will not affect the value returned from the call to
ToInt32. The tables below were generated using a bitwise
OR zero operation.

ToInt32 (col|0) : Numeric Values.

-1.6

-0

+0

1

1.6

8

16

16.8

123e-2

-Infinity

+Infinity

NaN

col|0

-1

0

0

1

1

8

16

16

1

0

0

0

NaN and ±Infinity become zero and
floating point values are truncated to integers.

ToInt32 (col|0) : String Values.

""(emptystring)

"-1.6"

"0"

"1"

"1.6"

"8"

"16"

"16.8"

"123e-2"

"010"(Octal)

"0x10"(Hex)

"0xFF"(Hex)

"-010"

"-0x10"

"xx"

col|0

0

-1

0

1

1

8

16

16

1

10

16

255

-10

0

0

String values that would type-convert to NaN are returned
as zero from ToInt32.

ToInt32 (col|0) : Other Values.

undefined

null

true

false

new Object()

function(){ return;}

col|0

0

0

1

0

0

0

Even undefined, objects and functions are converted to zero value
numbers by this operation. Note though that boolean true is
converted to the number 1.

Converting User Input

Most of the mechanisms for getting input from the user,
<input type="text"> and
prompt for example, provide their results in the form
of strings. If the user is expected to input a number they still
might enter anything (at the least they may just make a typo). If
the string needs to be converted into a number for later operations
one of the methods mentioned above can be chosen based on what best
suits the nature of the input expected but some of the results
generated with erroneous input may be difficult to detect and handle.

Prior to converting a string to a number it may be advantageous
to use a Regular Expression to test the contents of the string
to ensure that they conform to an acceptable format. That would
serve to eliminate some of the string values that may otherwise
suffer from the quirks of the string to number converting
processes when applied to unexpected string values.