Coercion in Java Script ( Type Conversion)

Primary data types in java scripts are numbers, string, boolean, null, undefined. So working with js most of the time we need to convert our data from one type to other type.

In js type conversion is bit scary but let's try to make it simple.

when we are dealing with non-primitive values and we want it to be primitive then JS runs an algorithm which has recursive steps to convert it to primitive.

if the conversion is to be done into string then algorithm follows below steps.

1)toString()

2)valueOf()

if toString methods returns primitive value then the algorithm will stop. if toString returns non-primitive then valueOf method is executed by algorithms. The result from valueOf method is Primitive then algorithm will stop otherwise it will return an error.

if the conversion is to be done into number then algorithm follows below steps.

1) valueOf()

2) toString()

For converting to number the steps are changed (i.e. first valueOf is checked then toString) other things done by algorithm is same only.

1) conversion into string

1) Primitive to string (toString for primitive)

here we are converting into string so according to algorithm first toString() will be checked, if result is not primitive then valueOf will checked.

null -> "null"

undefined -> "undefined"

true -> "true"

false -> "false"

3.1415 -> "3.1415"

0 -> "0"

-0 -> "0"

2)non-primitive to string (toString for non-primitive)

1) let's check for array

[] -> ""

[1,2,3] -> "1,2,3"

[null,undefined] -> ""

[[[], [], []], []] -> ",,,"

[,,,,] -> ",,,"

generally array will be converted as comma separated list of array items.

as we can see that while converting array to string at this time null, undefined, open square bracket ([) and close square bracket (]) are ignored.

[] array will be transformed into empty string.

[1,2,3] here this will be converted as comma separated list of array element so "1,2,3"

[null, undefined] here null and undefined are ignored so resultant will be [] that is converted to ""

[[[], [], []], []] here open and close square brackets are ignored so array will become [,,,] which will be converted into ",,,"

2)let's check for objects

for any kind of object toString will be "[object Object]" until toString method on object is not overridden.

{} -> "[object Object]"

{a:2} -> "[object Object]"

toOverride there are two options either specify on particular object or specify on Object.prototye.

ex. const obj = { name : "sahajanand", toString(){ return name }

when converting this object to string the toString method written on obj will be called which is returning "sahajanand".

2) converting into number

1) converting primitive into number

"" -> 0 (exception case)

"0" -> 0

"-0" -> -0

"009" -> 9

"3.142" -> 3.142

"0." -> 0

".0 " -> 0

"." -> NaN

false -> 0

true -> 1

null -> 0

undefined -> NaN

2)converting non-primitive into number

for array and object by default the valueOf method returns "this" (i.e. reference to itself). so according to algorithm valueOf returns non-primitive so algorithm will do toString for array and object and again the resultant string of toString method is converted into number.

let's see example for that.

remember that array elements are converted as comma separated list ignoring null, undefined, open ([) and close (]) square bracket.

[""] -> "" -> 0

here array element is empty single empty string so toString will return an empty string(""), so "" will be converted to 0.

["0"] -> "0" -> 0

["-0"] -> "-0" -> 0

[null] -> [] -> "" -> 0

[undefined] -> [] -> "" -> 0

[1,2,3] -> "1,2,3" -> NaN

[[[[[]]]]] -> [] -> "" -> 0

{} -> "[object Object]" -> NaN

3) conversion to boolean

conversion to boolean is too much simple. We just need to lookup the list of falsy values if our item is there then boolean conversion is false otherwise it will be true.

list of falsy values = '' , 0 ,-0, NaN, null, undefined, false

The values which are not in falsy list will be considered as truthy value.

let's look at some example.

{} -> true

[] -> true

0 -> false

2 -> true

Let's check for some example.

1) 1 < 2 < 3

1 < 2 is true. so true < 3. so true needs to coerced to number which is 1. so finally 1 < 3 which is true.

2) toNumber(["1"])

["1"] -> "1" -> 1.

3) const a = new Number(3)

const b = 3;

a === b // true

here var a is non primitive and we want to convert it to number so first valueOf will be checked which will returns 3. so 3 === 3 which is true.

4) Number({})

here {} will be check for valueOf method first because we are converting to number which will return {} itself. so converting {} to string.

so "[object Object]", which is string will be converted to number again which will be NaN