- Basics of Variables
- Working with Numbers
- Working with Strings
- Performing Type Conversions
- Review and Pursue
- Wrapping Up
Performing Type Conversions
Because JavaScript is weakly typed, different value types can be used together without causing formal errors. In, say, ActionScript, the following would cause an error:
var cost:int = 2; cost += ' dollars';
But in JavaScript, you can do that without the browser complaining. That being said, although you can use different types together without causing formal errors, it’s quite possible to end up with logical errors, which is to say bugs, if you’re not careful. One complication stems from the fact that the addition operator in math is the same as the concatenation operator for strings. When you add a string to a number, or add a number to a string, JavaScript will convert the number to a string and then concatenate the two. For example, say the shopping example added a shipping value to the total:
var shipping = document.getElementById('shipping').value; total = quantity * price; tax /= 100; tax++; total *= tax; total += shipping;
By the time JavaScript gets to the final line, total is a number, but shipping is a string, because it comes from a form’s text input. That final line won’t have the effect of mathematically adding the shipping to the total but rather concatenating the shipping onto the total (Figure 4.12).
Figure 4.12. Adding the string ‘5.00’ to the total has the impact of concatenation, converting the total number into an unusable string.
This issue doesn’t apply to other operators, though. For example, subtraction converts a string to a number and then performs the math, as the shopping example already demonstrated.
To perform math using strings, without worrying about creating bugs, you can forcibly convert the string to a number. There are many ways of doing so, starting with parseFloat() and parseInt(). These are “top-level” functions, which is to say they are not associated with any object and can be called directly. The first function always returns a floating-point number (aka, a decimal), and the latter, an integer. Both functions take the value to be converted as its first argument. The parseInt() function takes the radix as the second. The radix is the number’s base, as in base-8 (aka, octal), base-10 (decimal), and base-16 (hexadecimal). Although the second argument is optional, you should always provide it to be safe, and will normally use a value of 10:
total += parseFloat(shipping, 10);
To best use these functions, you should have an understanding of how they work. Both functions begin at the start of the string and extract a number until an invalid numeric character is encountered. If no valid number can be pulled from the start of the value, both functions return NaN (Figure 4.13):
parseInt('20', 10); parseInt('20.0', 10); parseInt('20 ducklings', 10); parseInt('I saw 20 ducklings.', 10);
Figure 4.13. How the parseInt() function extracts numbers from strings.
A trickier way to convert a string to a number is to prepend it with a +:
total += +shipping;
or
total += +(shipping);
Using this unary operator is the fastest solution, in terms of how quickly JavaScript performs the conversion, but is not as clear in terms of programmer readability as parseInt() and parseFloat().
Converting from a number to a string is far less likely to cause problems, but you can do so by invoking the toString() method:
var message = 'Your total is $' + total.toString();
The toString() method is supported by most objects and returns a string representation of the object itself.
Earlier in the chapter, I mentioned two other meaningful values in JavaScript: undefined and null. As a gotcha, you should be aware of what happens when an undefined or null value is used as if it were a number. The undefined value translates to NaN when used as a number. When a null value is used as a number, the result is better, although not great: null values are treated as 0 as numbers (Figure 4.14). In the next chapter, you’ll learn how to verify that a value is numeric prior to attempting to use it as such.
Figure 4.14. How arithmetic is handled if undefined or null is involved.