Type conversion (Definition)

Type conversion happens automatically as needed.

Availability:

ECMAScript edition - 2

JavaScript on the one hand is very good for the beginning programmer because it is very forgiving in regard to variable types. Other languages require that you define the type of a variable at the outset and only ever store the correct kind of data in it. JavaScript doesn't actually care and modifies the type of a variable on the fly according to the values being presented.

Type conversion happens automatically as needed. To support this, a set of polymorphic operators are provided to make the conversion.

The following internal operators are provided:

From the script writers point of view, these functions are inaccessible. However, you can call the constructors to invoke these functions indirectly.

The items of data themselves are still strongly typed, but the variable containers are smart enough to cope. There are some subtle rules to this however and you can create some situations where a very hard to diagnose problem occurs that is based on data typing inside the variables.

Type conversion happens during expression evaluation. You can still get rounding errors with Unary operators but you only need to worry about converting a single type.

If you think there is some ambiguity in your expression, you should force a conversion to the most appropriate type. Generally, object values should be converted to Numbers or Strings. Objects will generally have a preferred type that they yield when converted. In most cases that will be a number although Date objects prefer to become Strings.

Binary operators require two values and some require that both are of the same type or can be converted to the same type. If the type of the two operands is different, then you can have problems with some operators in expressions. If both need to be numeric for example, and once is not a legal numeric value even after conversion, then an error will result. The arithmetic and bitwise operators fall into that category.

The rest of the binary operators are polymorphic. That means they can cope with values of different types. The assignment operators will change the LValue to whatever type the RValue is. There is still some requirement here that the LValue is legally convertible. The comma operator doesn't combine its two operands in any way whatsoever.

Occasionally the interpreter may generate an error message due to its inability to legally convert a value to an appropriate type to complete the expression evaluation.

The relational operators cause some confusion since the values need to be converted for comparison but the relational comparisons work for several types. It is difficult to know what type will be used for the relational test unless you explicitly force a type conversion yourself.

The concatenation operator is also ambiguous because you may have two numeric strings and want to add them but the concatenate operator may join them together to make a string composed of both.

The addition/concatenation operator looks at the arguments and if either is a String already or preferentially converts to one, then a concatenation occurs. If neither operator prefers to be a String then a Number conversion happens and the values are added.

Relational operators perform the same deductive test. However, the conversion to Strings is less likely since relational operators are concerned with magnitude. However, they will test for collation order if both arguments are Strings.

Relational operators will attempt to convert both arguments to a Number and if they cannot, then they will use a String-based compare. If at least one argument can be converted to a Number then the other will be forced to be a Number for comparison purposes. So for a relation test to be String based, both arguments must be Strings, or string-like objects.

Tests for equality require further deductive reasoning on the part of the interpreter. The values are converted to their preferred types. If the types are the same then the values can be compared easily either as Numbers or Strings. If the types are different, then further conversion is necessary before the comparison can be completed. In that case, Boolean values become Numbers as do any other non-Numeric values and Numeric comparison predominates.

Comparing null with undefined values does not require any conversion and they will compare equal.

Warnings:

Example code:

   // String object scanned from numeric literal
   a = String(50);          // Equivalent to "50"
   
   // Number object scanned from string literal
   b = Number("22.22");     // Equivalent to 22.22
   
   // String literal coerced to numeric
   c = +("0x00FF");         // Equivalent to 255
   
   // String with number subtracted
   d = "22.22" - 11.11;     // Equivalent to 11.11
   
   // Logical operator on string and number
   e = ("abcde" && 23);     // Equivalent to 23
   
   // Bitwise operator on string and number
   f = ("0xF0" & 255);      // Equivalent to 240
   
   // Number coerced to string by concatenation
   g = "100" + 10;          // Equivalent to "10010"
   
   // Test for equallity of value
   h = ("100.1" == 100.1);  // Equivalent to true
   
   // Test for identity of instantiation
   i = ("100.1" === 100.1); // Equivalent to false
   
   // Object coerced to string forcing number to be concatenated
   j = (new Object) + 10;   // Equivalent to "[object Object]10"

See also:Add (+), Arithmetic operator, Bitwise operator, Boolean(), Cast operator, Equal to (==), Equality expression, JSObject.toString(), Logical operator, Math object, Math.abs(), Math.ceil(), Math.floor(), Math.round(), Minima-maxima, Number, Relational expression, String, String concatenate (+), ToBoolean, ToInt32, ToInteger, ToNumber, ToObject, ToPrimitive, ToString, ToUint16, ToUint32

Cross-references:

ECMA 262 edition 2 - section - 9

ECMA 262 edition 3 - section - 9

Wrox Instant JavaScript - page - 35

Wrox Instant JavaScript - page - 37