Abstract Value Operations

I have found that a lot of developers out there continually get confused about the result of converting certain value types to primitives. There is in fact a set of rules on how value types and specific values are converted to the different primitives. All this magic happens internally in abstract operations (ToString, ToNumber, TooBoolean and ToPrimitive) that contain the rules for the conversion.

ToString

This abstract operation handles the conversion of any non-string value. Primitives have the next stringification rules

null –> 'null'

undefuned –> 'undefined'

true –> 'true'

numbers –> A string representation of the number value. i.e 4 –> '4'

objects –> Unless specified something, the internal class will be returned. i.e [object Object]

arrays –> They are special. Their toString() function stringifies each value and concatenates all of them with a , between each

Let’s see a couple examples of this

var array = [1, 2, 3];
// Explicit coercion
array.toString(); // Output: 1, 2, 3

var number = 250;
// Explicit coercion
number.toString(); // Output: '250'

var boolean = true;
// Explicit coercion
boolean.toString(); // Output: 'true'

Please note that I added the comment Explicit coercion to each entry. This is just because I want to emphasize the coercion type being applied. It does not matter if coercion is explicit or implicit. When applied on non-string values and used in a string context the toString() function will always be called.

ToNumber

This abstract operation is defined for any non-number value that is required to be a number. Primitives have the next conversion rules

true –> 1

false –> 0

undefined –> NaN

null –> 0 // Curious ha?

string –> It works as expected. Please note that if the conversion fails then NaN is returned

objects

Objects (and arrays) are first converted to their primitive value equivalent. And if the primitive value is not already a number then the ToNumber function is applied.

Now the process to convert an object to primitive value goes like this: the ToPrimitive abstract operation is called and it will try to retrieve the value by checking for the existence of the valueOf function. If the function exists and it does return a primitive value then that value is returned and toNumber applies the rules explained above. But if the valueOf function is not defined and the toString() function it is then toString() will provide the primitive value. If both functions are not available or for some reason do not return a primitive value a TypeError exception is thrown.

ToBoolean

This abstract operation is by far the one that most confusion generates. I believe this is because most developers get started with object-oriented languages and they expect a similar behavior in JavaScript.

So first things first, yes JavaScript does have the true and false keywords and they behave exactly as you would expect and more importantly: any value being coerced to boolean will result in either true or false.

Falsy values

This concept is essentially how we describe a list of values that when coerced to boolean result in false. This is the falsy values list

  • undefined
  • null
  • false
  • +0
  • -0
  • NaN
  • ''

Not too long, ha? From this we can assume that if the value we are trying to coerce to boolean is not in this list. Then it will result in true meaning it is a truthy value.

No examples as I think I have been really clear.

Truthy values

These are basically all the values that when coerced to boolean result in true. Yes I know what you are thinking “Just give me the list”. But if you are paying attention you already figured it out. A truthy value is any value that does not belong to the falsy list.

Let the list of examples begin!

// This is me making you a big favor
var falseString = Boolean('false'); // Output: true 
var zeroString = Boolean('0'); // Output: true
var whiteSpaceString = Boolean(' '); // Output: true

So let’s examine what is going in on in the examples above. In the first example we are coercing the string 'false' to boolean. Now I know that in a lot of compiled languages this results in false, however not in JavaScript. Do you see the 'false' value in the falsy list? Me neither.

How about the zeroString variable? Well in that example we are coercing the string '0' to boolean but remember. The only string that results in false is the empty string. So result is as expected true

At this point I’d say you already figured out the last one. Yes a white space is not part of the list of the falsy values. So results is true

What an interesting set of rules, he? A good understanding of how JavaScript works behind the scenes makes things clearer and it is a great way to avoid some of the issues that most developers face when not having this knowledge.

Thanks for reading and have a happy coding!