Left ArrowBack

notes / JavaScript / types / coercion

coercion

The word true, the number 1 & quotes

JavaScript Coercion

Planted

Status: seed

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

Console

const a = 42;

// explicit coercion
const c = String(a);

// implicit coercion
const b = a + "";

M

etaphor:

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 & 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

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:

/index.js

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.

/index.js

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 becomes 1
  • false becomes 0
  • undefined becomes NaN
  • null becomes 0
  • string: "1" becomes 1, "a" becomes NaN

To coerce an Object value:

  1. 1. The ToPrimitive() abstract operation will check if the object has a valueOf() method.
    • if it exists & 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. 2. The primitive value will be coerced as per the ToNumber rules above.

/index.js

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 & stops when a non-numeric value is found.

/index.js

Console

const a = "42px";

console.log(Number(a));
console.log(parseInt(a));

ToBoolean

The ToBoolean abstract operation rules are:

  • undefined becomes false
  • null becomes false
  • +0, -0, & NaN becomes false
  • "" becomes false
  • all other values become true

Boolean(myVar) or !!myVar can be used.

/index.js

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 (..) & do..while(..) loop.
  • The test expression (1st clause) in a ? : ternary expression.
  • The left-hand operand to the || and && operators.
Ani's soul, represented by a bird with a human head, observes as Anubis weighs Ani's heart

Equality

When comparing 2 values for equality, commonly used operators are:

  • loose equality: ==
  • strict equality: ===

Loose allows coercion. Strict doesn't.

/index.js

Console

const a = 42;
const b = "42";

console.log(a == b);
console.log(a === b);

Where to Next?

A sci-fi robot taxi driver with no lower body