JavaScript is very tolerant when it comes to accepting values. For example, everywhere it expects a number, it does not reject values from other types, but tries to convert them:
> '5' - '2'
3
> '5' * '2'
10
Automatic conversion to boolean is rarely problematic and often useful. It is covered here as a preparation for later – we’ll use it to work around quirks. Automatic conversion to string, however, can cause problems.
> Boolean(undefined)
false
> Boolean(0)
false
> Boolean(3)
true
> var x = '5'; // wrong assumption: x is a number
> x + 1
'51'
Furthermore, there are a few falsy values that are truthy if converted to string. Example: false.
> Boolean(false) // truthy?
false
> String(false)
'false'
> Boolean('false') // truthy?
true
Example: undefined.
> Boolean(undefined) // truthy?
false
> String(undefined)
'undefined'
> Boolean('undefined') // truthy?
true
> 3 * { valueOf: function () { return 5 } }
15
Example for step 3:
> function returnObject() { return {} }
> 3 * { valueOf: returnObject, toString: returnObject }
TypeError: Cannot convert object to primitive value
If JavaScript converts to string, steps 1 and 2 are swapped: toString() is tried first, valueOf() second.
function handleFormData(formData) {
var givenName = String(formData.givenName);
var age = Number(formData.age);
...
}
These functions always return a value (they never throw an exception). However, Number() returns the error value NaN [1] if it can’t convert a value:
> Number('xyz')
NaN
> Number(undefined)
NaN
> Number(null)
0
> Number(true)
1
A more elaborate solution would be to first check whether the value you are converting has the correct format (e.g. someone shouldn’t enter 'xyz' as their age) and to take appropriate measures if it doesn’t.