
JavaScript Coercion
Planted:
Status: decay
Hits: 66
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
:
index.js
const a = 42;// explicit coercionconst c = String(a);// implicit coercionconst b = a + "";
Coercion is like translating a word from 1 language to another. For example, translating the word apple from English to German. A translator will look at all the words available in the German language. Then, pick 1 that best matches the English word's meaning. In this case, apfel.
The translator is the JavaScript engine, the word is a value and the languages are JavaScript's types.
Imagine the engine needs to coerce a value from a string
to a boolean
.
The engine looks at the available "words" in the boolean
"language".
There are only 2, true
or false
.
Whichever is selected, a lot of the string's meaning will be lost in translation.
But that is the nature of coercion.
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).
index.js
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:
index.js
const a = 1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;const aStr = a.toString();// seven times three digits => 21 digitsconsole.log(aStr)
Object values have their own toString()
method.
If you implicitly coerce an object, its toString()
will automatically be called.
index.js
const obj = [1,2];// explicitconsole.log(obj.toString())// implicit// if either operand to '+' is a string, the operation will be string concatenationconsole.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.
index.js
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.
index.js
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.
index.js
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.
index.js
const a = 42;const b = "42";console.log(a == b);console.log(a === b);
Feedback
Have any feedback about this note or just want to comment on the state of the economy?