Primitives, Truthy and Falsey

How does JavaScript compare to Ruby?

JavaScript Primitive Data Types in JavaScript and Ruby

JavaScript Primitive Data Types

A primitive data type in JavaScript is data that is not an object and has no methods.

There are 7 primitive types: undefined, null, boolean, string and number, symbol and bigint. Everything else in JavaScript is an is an object.

Here’s a breakdown:

undefined: the value assigned variables that have been declared, but have no valuenull: Nothing. Something that doesn't exist. The programmer sets a value to null to convey this.boolean: true/falsestring: a sequence of characters used to represent textnumber: a numbersymbol: a unique identifier type, with specific use case, see belowbigint: like numbers but allows large integers beyond the safe integer limit for numbers. Use for big integers.

In JavaScript, undefined behaves and is meant to be used differently than null. A null value is usually set on a variable by the programmer to signify that the value of that variable is nothing. If a variable is not assigned a value when instantiated, its value will be undefined until value is assigned within the program.

Undefined vs. null in JavaScript

undefined:let person = {firstName:"John", lastName:"Doe", age:50}
person = undefined // Now both value and type is undefined
console.log(person)
//=> undefined
console.log(typeof(person))
//=> undefined
null:let person = {firstName:"John", lastName:"Doe", age:50}
console.log(person)
//=> {firstName: "John", lastName: "Doe", age: 50}
person = null // Now value is null, but type is still an objectconsole.log(person)
//=> null
console.log(typeof(person))
//=> object

Symbols are a new primitive type, with a specific use case. Symbols were introduced in ES6. They are not that common, so I will not go into detail about them here. Check out my blog post to learn more about how and when to use them.

Like Symbols, BigInts have their specific use cases. For instance, maybe the need is to use an integer that is larger than what Number can handle. More details about BigInts can be found on the Mozilla JavaScript data types and data structures doc.

Why is this important?

A common situation arises in programming where the logic of the program based on a whether a value is true or not. For example:

if(someValue) {
doSomething()
}
else {
doSomethingElse()
}
or, more succinctly, with a ternary:
someValue ? doSomething() : doSomethingElse()

JavaScript will implicitly convert someValue to a true or false based on certain rules. For example, here is how the primitive types convert to boolean when forcing the value to a boolean through use of a ternary rather than an if statement.

let value = undefined //value is undefined
console.log(value ? true : false)
//=>false (undefined is converted to false, making undefined "falsey")
value = null //value is null
console.log(value ? true : false)
//=>false (null is is converted to false, making null "falsey")
value = true
console.log(value ? true : false)
//=>true (true is a boolean, which is "truthy")
value = false
console.log(value ? true : false)
//=>false (false is boolean, which is "falsey")
value = 1
console.log(value ? true : false)
//=>true (1 is a number, converted to true, making 1 "truthy")
value = Symbol()
console.log(value ? true : false)
//=>true (value is a symbol, converted to true, making Symbols "truthy")
value = 2n
console.log( value ? true : false)
//=>true (value is a bigint, converted to true, making BigInts "truthy")

We can use this behavior to our advantage and write shorter, clearer code, if we know how JavaScript will handle the conversion primitive data type values to boolean values.

Additionally, JavaScript will convert the following values to false and are “falsey”.

value = 0 //zero
console.log(value ? value = Symbol()
console.log(value ? true : false)
//=>false (0 is the only number converted to false or "falsey")
value = "" //empty string
console.log( value ? true : false)
//=>false (empty string is converted to false or "falsey")
value = null
console.log( value ? true : false)
//=>false (null is converted to false or "falsey")
value = undefined
console.log( value ? true : false)
//=>false (undefined is converted to false or "falsey")
value = Number(undefined)
console.log('value', value) //value NaN
console.log( value ? true : false)
//=>false (NaN is converted to false or "falsey")

Take note that empty objects (which are not primitives) in JavaScript convert to true:

value = {}
console.log( value ? true : false)
//=>true ({} is converted to true, or "truthy")

Empty arrays are also converted to true:

value = []
console.log( value ? true : false)
//=>true ([] is converted to true, or "truthy")

Knowing these rules is helpful to write code that succinct, predictable and less buggy.

So, how does Ruby do it?

In Ruby there are no primitive data types. Every value is an object. Ruby does implicit conversions as JavaScript does, but slightly differently. Let’s do some tests in the Ruby console to see how things compare.

2.7.0 :001 > value = nil
2.7.0 :002 > value ? true : false
=> false (nil evaluates to false)
(similar to null in JavaScript)
2.7.0 :001 > value = true
2.7.0 :002 > value ? true : false
=> true (true is true)
2.7.0 :005 > value = false
2.7.0 :006 > value ? true : false
=> false (false is false)
2.7.0 :007 > value = 1
2.7.0 :008 > value ? true : false
=> true (1 is converted to true)
2.7.0 :012 > value = {}
2.7.0 :013 > value ? true : false
=> true (an empty hash is converted to true)
2.7.0 :012 > value = []
2.7.0 :013 > value ? true : false
=> true (an empty array is converted to true)

So far so good, pretty much the same as how JavaScript does it. However, after more testing, we notice that Ruby converts 0 (zero) and “” (empty string) to true, while JavaScript converts these two values to false. Damn.

2.7.0 :007 > value = 0
2.7.0 :008 > value ? true : false
=> true (0 is converted to true)
// this is different than in JavaScript
2.7.0 :018 > value = ""
2.7.0 :019 > value ? true : false
=> true ("" is converted to true)
// this is different than in JavaScript

Keeping aware of these differences between languages is important to remember. Moving back and forth between front end JavaScript code and a Ruby back end can be a headache when forgetting subtle differences in the languages.

References

https://stackoverflow.com/questions/18790442/are-there-primitive-types-in-ruby
https://www.w3schools.com/js/js_type_conversion.asp

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store