JavaScript Coercion
Planted:
Status: decay
A type can be converted in 2 different ways:
- ▪ Type casting: explicitly converting a value from 1 type to another. Occurs in statically typed languages at compile time. TypeScript example:
const myVar = otherVar as string
. - ▪ Coercion: occurs in dynamically typed languages, like JavaScript, at runtime. It can happen in 2 different ways:
- ▫ explicit: it's obvious the intent is to convert a value from one type to another.
- ▫ implicit: type conversion occurs as a side-effect of some operation.
Example, coercing a number
into a string
:
Console
const a = 42; // explicit coercion const c = String(a); // implicit coercion const b = a + "";
Whenever coercion occurs, 1 or more internal operations, known as abstract operations, are performed. It always results in a primitive.
Explicit Coercion
To explicitly coerce a value to a string, number or boolean, use the built-in native contructors.
The new
keyword isn't used (so an object wrapper isn't created).
Console
const a = 1; const b = String(a); const c = "1"; const d = Number(c); const e = "1"; const f = Boolean(c);
These constructors can coerce any value to a primitive based on the rules of the abstract operations:
- ▪
ToString
- ▪
ToNumber
- ▪
ToBoolean
ToString
The ToString
abstract operation rules are:
- ▪
null
becomes"null"
- ▪
undefined
becomes"undefined"
- ▪
true
becomes"true"
- ▪ number:
1
becomes"1"
. Very small or large numbers become their exponent form:
Console
const a = 1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000; const aStr = a.toString(); // seven times three digits => 21 digits console.log(aStr)
Object values have their own toString()
method.
If you implicitly coerce an object, its toString()
will automatically be called.
Console
const obj = [1,2]; // explicit console.log(obj.toString()) // implicit // if either operand to '+' is a string, the operation will be string concatenation console.log(obj + "")
ToNumber
The ToNumber
abstract operation rules are:
- ▪
true
becomes1
- ▪
false
becomes0
- ▪
undefined
becomesNaN
- ▪
null
becomes0
- ▪ string:
"1"
becomes1
,"a"
becomesNaN
To coerce an Object value:
- 1. The
ToPrimitive()
abstract operation will check if the object has avalueOf()
method.- ▫ if it exists and it returns a primitive value, that value will be used
- ▫ if it doesn't exist, but
toString()
does, its return value will be used - ▫ if neither exist or don't return a primitive, a TypeError is thrown
- 2. The primitive value will be coerced as per the
ToNumber
rules above.
Console
const objA = { valueOf: function(){ return 1; } }; const objB = { toString: function(){ return "1"; } }; const objC = [4,2]; objC.toString = function(){ return this.join( "" ); }; console.log(Number(objA)) console.log(Number(objB)) console.log(Number(objC)) console.log(Number([])) console.log(Number(["abc"]))
parseInt
parseInt(..)
can be used to get a numeric value out of a string containing non-numeric characters.
It parses left-to-right and stops when a non-numeric value is found.
Console
const a = "42px"; console.log(Number(a)); console.log(parseInt(a));
ToBoolean
The ToBoolean
abstract operation rules are:
- ▪
undefined
becomesfalse
- ▪
null
becomesfalse
- ▪
+0
,-0
, andNaN
becomesfalse
- ▪ "" becomes
false
- ▪ all other values become
true
Boolean(myVar)
or !!myVar
can be used.
Console
var myVar = 1; console.log(Boolean(myVar)); console.log(!!myVar);
Implicit Coercion
Expression operations that are implicitly coerced to a boolean:
- ▪ The test expression in an
if (..)
statement. - ▪ The test expression (2nd clause) in a
for ( .. ; .. ; .. )
header. - ▪ The test expression in
while (..)
anddo..while(..)
loop. - ▪ The test expression (1st clause) in a
? :
ternary expression. - ▪ The left-hand operand to the
||
and&&
operators.

Equality
When comparing 2 values for equality, commonly used operators are:
- ▪ loose equality:
==
- ▪ strict equality:
===
Loose allows coercion. Strict doesn't.
Console
const a = 42; const b = "42"; console.log(a == b); console.log(a === b);