
JavaScript Coercion
Planted:
Status: decay
Hits: 88
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:
- ▪
nullbecomes"null" - ▪
undefinedbecomes"undefined" - ▪
truebecomes"true" - ▪ number:
1becomes"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:
- ▪
truebecomes1 - ▪
falsebecomes0 - ▪
undefinedbecomesNaN - ▪
nullbecomes0 - ▪ 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
ToNumberrules 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:
- ▪
undefinedbecomesfalse - ▪
nullbecomesfalse - ▪
+0,-0, andNaNbecomesfalse - ▪ "" 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?



