DEV Community

loading...
Cover image for Data Types and Operators in JavaScript: Everything You Need To Know

Data Types and Operators in JavaScript: Everything You Need To Know

Joel P. Mugalu
JavaScript Developer
・10 min read

According to Wikipedia:

A data type or simply type is an attribute of data which tells the compiler or interpreter how the programmer intends to use the data. This data type defines the operations that can be done on the data, the meaning of the data, and the way values of that type can be stored.

In simple terms a data type is a type of value. A data type tells the programming language how the value is meant to be used and the operations that can be carried out on it.

In this article we are going to explore all the details of different data types in JavaScript and the operations that can be carried out on them. This is an in depth article so you might want to grab a pen and paper.

JavaScript has two main types of data types: primitive data types and objects. Let's explore both of them.

Primitive Data Types

A primitive data type can be understood as a basic data type in JavaScript. Some primitive data types only accept a set value(s) and others accept certain type of values.Primitive data types are immutable. That means their values cannot be changed or mutated. I'll further explain this in the article.
Let's look at the primitive data types in JavaScript.

Numbers

Values of the number type are numeric values written as usual numbers like 12, 67 and 85.

JavaScript uses 64 bits to store a number. Given 64 bits JavaScript can represent up to 18 quintillion numbers. You don't have to remember that number. The point is we can write very huge numbers with JavaScript.

All operations carried out on whole numbers are guaranteed to be precise and accurate.

console.log(12 + 67) //79
console.log(1234597654 + 987654132476 ) //988888730130
Enter fullscreen mode Exit fullscreen mode

Sadly that is not the case with floating point numbers. In JavaScript floating point numbers are numbers that have decimal points.
Take a look at this example:

console.log(0.1 + 0.2 === 0.3) //false
console.log(0.1 + 0.2) //0.30000000000000004
Enter fullscreen mode Exit fullscreen mode

Looking at the example you would expect that adding 0.1 + 0.2 would result in 0.3. Instead we get 0.30000000000000004. Why is that?

In real math we have an infinite set of numbers to work with. In JavaScript we only have 64 bits (18 quintillion numbers). Therefore we cannot precisely represent floating point numbers with only 64 bits. When you add 0.1 + 0.2 JavaScript returns the closest available number. This doesn't need to get you worried unless you want to calculate the precise age of the universe.

Let's look at the operations we can carry out on numbers.

Arithmetic Operations

You've probably guessed already that we can carry out arithmetic operations on numbers in JavaScript.

Just like usual math we can add, subtract, multiply and divide numbers. The symbols used to carry out these operations are called operators. The + operator is used for addition, - for subtraction, * for multiplication and / for division.

console.log(1 + 2) //3
console.log( 10 - 5) //5 
console.log( 2 * 100) //200
console.log(120 / 2) //60
Enter fullscreen mode Exit fullscreen mode

However, when working with operators we must look out for something called operator precedence.

According to Mozilla Developer Network (MDN):

Operator precedence determines how operators are parsed concerning each other. Operators with higher precedence become the operands of operators with lower precedence.

Let's look at this code

console.log(2 + 2 * 10 === 40) //false
console.log(2 + 2 * 10 === 22) //true
Enter fullscreen mode Exit fullscreen mode

Operations in JavaScript do not occur from left to right. Rather some operators take precedence over others. So 2 + 2 * 10 is not 4 * 10 = 40 but 2 + 20 = 22 because * has a higher precedence than + so that operation happens first.

If you would like to carry out arithmetic operations left to right, you can do so with parenthesis.

console.log((2 + 2) * 10 == 40); //true
Enter fullscreen mode Exit fullscreen mode

You can read more about operator precedence here.

Special Numbers

As it turns out, not all numbers have a numeric value in JavaScript. JavaScript has three special numbers. Infinity for positive infinities, -Infinity for negative infinities and NaN which means "Not a Number".
These special numbers are used to represent foul operations.

console.log(1 / 0) //Infinity
console.log(-1 / 0) //-Infinity
console.log(0 / 0) //NaN
Enter fullscreen mode Exit fullscreen mode

NaN is of special interest because it's quite the trouble causer. It's a number that means "Not A Number". This can be very confusing at times.

According to MDN:

There are five different types of operations that return NaN:

  • Number cannot be parsed (e.g. parseInt("blabla") or Number(undefined))
  • Math operation where the result is not a real number (e.g. Math.sqrt(-1))
  • Operand of an argument is NaN (e.g. 7 ** NaN)
  • Indeterminate form (e.g. 0 * Infinity)
  • Any operation that involves a string and is not an addition operation (e.g. "foo"/3)

You can test for NaN using the method Number.isNaN(number)

So, simply put NaN is a numeric value that represents an invalid result.

Let's look at another data type.

Strings

A string is another data type in JavaScript. Strings represent text. This text can be enclosed in either single quotes '', double quotes "" or back ticks ().

console.log("This is text");
console.log('This is also text');
Enter fullscreen mode Exit fullscreen mode

Interestingly though, strings are not just text in JavaScript. Behind the scenes each letter in a string is a number. If you've ever heard of the ASCII standard then this is it. Each character in a computer has a number assigned to it. For example lower case a is 65 and uppercase A is 97. Same with all the other letters and characters.

However, the ASCII standard was limited in the number of characters it could represent. This led to the birth of the Unicode standard. With the Unicode standard, just about any character can be represented with a number. Even Emojis. That was just an interesting fact.

We can't carry out subtraction, multiplication and division on strings. Doing so would yield to NaN which we just talked about.

console.log("No" * "Arithmetic") //NaN
Enter fullscreen mode Exit fullscreen mode

But, we can use the addition operator on strings. This is called string concatenation. This way we can join two strings into one.

console.log("Yes" + " Concatenation") //Yes Concatenation
Enter fullscreen mode Exit fullscreen mode

We can also use bracket notation to access individual characters in a string. But we cannot change these characters. As I mentioned earlier this is because primitive data types are immutable. If we try to mutate strings, JavaScript will throw an error if in strict mode

'use strict'
let myUsername = "codingknite";
console.log("myUsername[0]") //c
myUsername[0] = 'k'; // Throws error
Enter fullscreen mode Exit fullscreen mode

Boolean

Boolean is another data type in JavaScript with only two values written as true and false. Logical operations can be carried out with Boolean. Think of boolean as answers to yes or no questions that we ask JavaScript.

console.log(5 > 2) //true
console.log(10 > 120) //false 
Enter fullscreen mode Exit fullscreen mode

There's quite a number of operators we can use to carry out operations on boolean.

Equality Operators

Equality operators are used to compare whether or not two values are equal to each other. The result is a boolean value.

  • The (==) operator denotes "equal to"
  • The (!=) operator denotes "not equal to"
  • The (===) operator denotes "strictly equal to"
  • The (!==) operator denotes "strictly not equal to"
console.log(2 == 2) //True 
console.log("apple" == "pineapple") //false
console.log("JavaScript" === "JavaScript") //true
console.log("JavaScript" !== "Java") //true
Enter fullscreen mode Exit fullscreen mode

There is one value in JavaScript which in not equal to itself. And it's none other than NaN

console.log(NaN === NaN) //false 
Enter fullscreen mode Exit fullscreen mode

According to MDN:

Unlike all other possible values in JavaScript, it is not possible to rely on the equality operators (== and ===) to determine whether a value is NaN or not, because both NaN == NaN and NaN === NaN evaluate to false. Hence, the necessity of an isNaN function.

The issue with NaN not being equal to NaN is historical. Just Accept it as a fact of life. If you're interested in reading more about NaN and why it's not equal to itself, consider reading this article

There is a one difference between the equality operator and the strict equality operator which i'll get to in a second.

Comparison Operators

Comparison operators are used to compare two or more values. The result is either of the boolean values.

These are the most common comparison operators.

  • The ( > ) operator is used to denote "greater than"
  • The ( < ) operator is used to denote "less than" console.log(5 > 3) //true console.log(10 < 15) //false
  • The ( >= ) operator denotes "greater than or equal to"
  • The ( <= ) operator denotes "less than or equal to"
  • The ( == ) operator denotes "equal to"
  • The ( === ) operator denotes "strictly equal to"

Logical Operators

Logical Operators are used to compare two conditions. JavaScript has three main logical operators.

AND Operator

The AND operator written as && compares two values and returns true if both values on the left and right equate to true. Otherwise is returns false.

console.log(5 > 2 && 10 >8) //true
console.log( 5 > 2 && 8 > 10) //false
Enter fullscreen mode Exit fullscreen mode

OR Operator

The OR operator written as || compares two values and returns true if either value on the left or right equates to true. Otherwise it returns false.

console.log(5 > 3 &&  10 === 10) //true
console.log(10 === 12 && 120 < 100) //false
Enter fullscreen mode Exit fullscreen mode

NOT Operator

The NOT operator written as ! flips any value given to it. In other words !true becomes false and !false becomes true.

console.log(true !== true) //false
console.log("apple" !== "pineapple") //true 
Enter fullscreen mode Exit fullscreen mode

Automatic Type Coercion

When JavaScript receives the wrong values, it changes the data type of the resulting value.

Let's Look at some code

console.log(12 * '3'); //36
console.log("50" - 12); //38
console.log(true + 12); //13
console.log("Thirteen" * 2); //NaN
console.log(false + 1); //1
Enter fullscreen mode Exit fullscreen mode

As we see in the code above JavaScript secretly changes the types when it receives unusual values. The string '3' on the first line becomes the number 3. Same as the string "50". On the third line true becomes 1 and false becomes 0.

Type coercion is what creates the difference between the equality operator and the strict equality operator.

console.log(1 == '1') //true 
console.log(1 === '1') //false
Enter fullscreen mode Exit fullscreen mode

The equality operator carries out type coercion on the values it receives where as the strict operator does not carry out type coercion. This is why most JavaScript developers consider it a good practice to use the strict equality operator. To avoid unnecessary type coercion.

Let's now look at the last two primitive data types

Null

Null is a primitive data type in JavaScript used to represent an intentionally missing value. Null has only one value and that is null. Null is a falsy value because it returns false in all boolean operations

console.log(!null) //true
console.log(null === null) //true
Enter fullscreen mode Exit fullscreen mode

Undefined

Undefined is also a primitive data type in JavaScript and just like Null it has only one value undefined. It represents an unintentionally missing value. Undefined is also considered a falsy value because it returns false in boolean operations. When comparing null and undefined it's very important to look out for the equality and strict equality operators.

console.log(null == undefined) //true
console.log(null === undefined) //false
console.log(!undefined) //true
Enter fullscreen mode Exit fullscreen mode

There you have it. These are the primitive data types in JavaScript. But that's not all.

Truthy and Falsy Values

Falsy values are values that are return false in a condition.
JavaScript has 5 basic falsy value: undefined, null, 0, '', NaN

Truthy values are all the other values that are !falsy values (>_-)

let age = 23;
if (age || age === 0) {
    console.log('Age is defined'); 
} else {
    console.log('Age is not defined');
}
// returns 'Age is defined';
Enter fullscreen mode Exit fullscreen mode

Try to figure out why the above code logs 'Age is defined'

Unary Operator

A Unary operator is an operator that accepts only one value.

The best example of a unary operator is the typeof operator which returns the type of value specified. In fact we can use this operator to check out all the data types we've talked about.

console.log( typeof 'text') //string
console.log( typeof 25) //number
console.log( typeof true) //boolean
console.log( typeof false) //boolean
console.log( typeof null) //object
console.log(typeof undefined) //undefined
Enter fullscreen mode Exit fullscreen mode

If you noticed, the typeof null returned object. I will explain why that is so in the next article.

Binary Operators

Binary Operators are operators that carry out operations on two values

console.log(1 + 1) //2
console.log(12 - 5) //7
Enter fullscreen mode Exit fullscreen mode

Ternary Operator

The ternary operator is used to check a condition and return a value based on whether or not the condition is true. It's like a quick if statement.

The basic frame of a ternary operator is:

condition ? return value if true : return value if false
Enter fullscreen mode Exit fullscreen mode

Let's look at this code

15 > 12 ? console.log("15 is greater than 12") : console.log("15 is less than 12"); // 15 is greater than 12
Enter fullscreen mode Exit fullscreen mode

Well, that's everything you need to know about primitive data types.
What is the second type of data types in JavaScript?

Objects and Functions

Now i don't know about you but that's enough data types for one day. In my next article am going to talk about objects and everything you need to know about them. So stay tuned.

However, if you're interested I've written a blog post on functions. You can check it out here if you wish.

SUMMARY

So, what have we seen.

  • A data type is basically the way a programming language understands the data it receives telling it how the data is to be used.
  • Operations are basically the way we use the data received *There are two types of data types

Primitive Data Types
There are five main primitive data types

  1. Numbers

    • Numeric Values
    • Arithmetic operations like Addition, Subtraction, Multiplication and division can be carried out on them.
  2. Strings

    • How text is represented
    • + can be used on them for concatenation.
  3. Boolean

    • Used for logical operations -Two values written as true and false
  4. Null

    • Intentionally missing values
    • Only one value null
    • Falsy value
  5. Undefined

    • Unintentionally missing values
    • Only one value undefined
    • Also a falsy value

Conclusion

I hope you enjoyed this article. If you would like to follow my coding journey and be the first to know when I release a new article, be sure to follow me on Twitter

Discussion (7)

Collapse
pentacular profile image
pentacular

Rather some operators take precedence over others. So 2 + 2 * 10 is not 4 * 10 = 40 but 2 + 20 = 22 because * has a higher precedence than + so that operation happens first.

It's not the order of operation that is determined by associativity, but to which operator an operand is associated.

Execution order is a separate issue.

The ternary operator is used

It's always struck me as silly that people call it "the ternary operator" because it has three operands, rather than "the conditional operator" which is about what it does. :)

It represents an unintentionally missing value.

Perhaps unset value would be closer to it?

Collapse
codingknite profile image
Joel P. Mugalu Author

Hey...I appreciate your comment.

Regarding operator precedence, I'm not sure I understand what you're trying to say. Perhaps it's how I explained it.
The following is the definition of operator precedence according to Wikipedia

"In mathematics and computer programming, the order of operations is a collection of rules that reflect conventions about which procedures to perform first in order to evaluate a given mathematical expression"

And that Is what I meant...operators with higher precedence are evaluated before operators with a lower precednce. Hence the multiplication happens before addition...because (*) has a higher precedence than (+).

As for the ternary operator...its called the conditional (ternary) operator. I don't think it makes any sense to be dogmatic about it. I think what matters is understanding what it does rather than being religious about what its called.

For undefined, unset value is actually easier a definition. So I'm going to in cooperate that. Otherwise thanks for your views.

Collapse
pentacular profile image
pentacular

"In mathematics and computer programming, the order of operations is a collection of rules that reflect conventions about which procedures to perform first in order to evaluate a given mathematical expression"

Yeah, I can see where this is coming from, but it's fundamentally incorrect.

You can think of predecence as showing where parentheses should be inserted to make the association of operand to operator clear.

e.g., a + b * c + d might become a + ((b * c) + d).

But this doesn't actually tell us what order the evaluation occurs in, and the system is free to rearrange things providing that these constraints are met.

For example, the system may understand that since x + y + z is equivalent to x + z + y, it can turn a + ((b * c) + d) into (a + b) + (b * c).

And, of course, it is free to evaluate a, b, c, and d in any order it likes, since there are no topological dependencies between those operations.

In javascript, evaluation is specified as being left-to-right, which means that if you run

const p = (v) => (console.log(v), v);
p(1) + (p(2) * p(3)) + p(4);
// You'll get 1, 2, 3, 4 output.

I really wish they'd stop calling operator associativity 'order of operations' because it's (a) wrong, and (b) misleads people into thinking of mathematics as a mechanical process, rather than being about relationships. :)

As to the 'ternary operator' ...

If the only binary operator were +, would you start calling it 'the binary operator'? :)

Collapse
andreespirela profile image
andreespirela

Very great great article. I liked how you structured it, and how you explain how to use these datatypes in conditionals. You forgot two datatypes:
BigINT: developer.mozilla.org/en-US/docs/W...

And binary representations: developer.mozilla.org/en-US/docs/W...

Anyway, great article. Keep it up

Collapse
codingknite profile image
Joel P. Mugalu Author

Yes I've slightly read about BigInt but I've not yet fully understood it. I did not want to write about something i didn't fully understand.

As for the second one...I just heard about it from you right now LOL. I'll update the article when I've comfortably understood them. Thanks though.

Collapse
codingknite profile image
Joel P. Mugalu Author • Edited

Thanks man...I appreciate your feedback. Took me a while to write this one but am glad it helped you. Definitely writing more articles