JavaScript Primitive Data Types
Tags: javascript, beginners, react, programming
Published: 2024-04-01 15:01:28

In JavaScript, primitive data types are the predefined data types provided by the language itself. They are also known as in-built data types. JavaScript has seven primitive data types: Number, String, Boolean, Undefined, Null, Symbol, and BigInt

## **Primitive data types**

We'll go over each of the primitive types one-by-one, starting with numbers.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/733mdw6ux6am76cjmku0.png)





## **Null**

The null value represents the intentional absence of any object value. It is one of JavaScript's primitive values and is treated as **falsy** for **boolean** operations.

```
function getVowels(str) {
  const m = str.match(/[aeiou]/gi);
  if (m === null) {
    return 0;
  }
  return m.length;
}

console.log(getVowels('sky'));
// Expected output: 0
```

**Syntax** -> null

The value null is written with a literal: **null**. null is not an identifier for a property of the global object, like undefined can be. Instead, null expresses a lack of identification, indicating that a variable points to no object. In APIs, null is often retrieved in a place where an object can be expected but no object is relevant.

```
// foo does not exist. It is not defined and has never been initialized:

foo; //ReferenceError: foo is not defined

```

```
// foo is known to exist now but it has no type or value:
const foo = null;
foo; //null

```

## **Undefined**

The Undefined type is inhabited by exactly one value: undefined.

Conceptually, undefined indicates the absence of a value, while null indicates the absence of an object (which could also make up an excuse for typeof null === "object"). The language usually defaults to undefined when something is devoid of a value:

- A return statement with no value (return;) implicitly returns **undefined**.
- Accessing a nonexistent object property (obj.iDontExist) returns **undefined**.
- A variable declaration without initialization (let x;) implicitly initializes the variable to **undefined**.
- Many methods, such as Array.prototype.find() and Map.prototype.get(), return undefined when no element is found.

null is used much less often in the core language. The most important place is the end of the prototype chain — subsequently, methods that interact with prototypes, such as Object.getPrototypeOf(), Object.create(), etc., accept or return null instead of undefined.

null is a keyword, but undefined is a normal identifier that happens to be a global property. In practice, the difference is minor, since undefined should not be redefined or shadowed.

**Difference between null and undefined**:-

When checking for null or undefined, beware of the differences between equality (==) and identity (===) operators, as the former performs type-conversion.

```
typeof null; // "object" (not "null" for legacy reasons)
typeof undefined; // "undefined"
null === undefined; // false
null == undefined; // true
null === null; // true
null == null; // true
undefined === undefined; // true
undefined == undefined; // true
!null; // true
Number.isNaN(1 + null); // false
Number.isNaN(1 + undefined); // true

```

## **Boolean**

The Boolean type represents a logical entity and is inhabited by two values: true and false.

Boolean values are usually used for conditional operations, including ternary operators, if...else, while, etc.


**Boolean primitives and Boolean objects**

For converting non-boolean values to boolean, use Boolean as a function or use the double NOT operator. Do not use the Boolean() constructor with new.

`const good = Boolean(expression);
const good2 = !!expression; // you do use this!`

`const bad = new Boolean(expression); // don't use this!`

> This is because all objects, including a **Boolean object** whose wrapped value is false, are truthy and evaluate to true in places such as conditional statements. (See also the boolean coercion section below.)

```
console.log(typeof new Boolean()) // object

console.log(new Boolean()) // [Boolean: false]

console.log(new Boolean(true)) // [Boolean: true]
```

```
if (new Boolean(true)) {
  console.log("This log is printed.");
}
// This log is printed.

if (new Boolean(false)) {
  console.log("This log is ALSO printed.");
}
//This log is ALSO printed.

if (new Boolean()) {
  console.log("This log is also printed.");
}
// This log is ALSO printed.

const myFalse = new Boolean(false); // myFalse is a Boolean object (not the primitive value false)
const g = Boolean(myFalse); // g is true
const myString = new String("Hello"); // myString is a String object
const s = Boolean(myString); // s is true
```

**_<u>Boolean coercion</u>_**

Many built-in operations that expect booleans first coerce their arguments to booleans. The operation can be summarized as follows:

- undefined turns into false.
- null turns into false.
- 0, -0, and NaN turn into false; other numbers turn into true.
- 0n turns into false; other BigInts turn into true.
- The empty string "" turns into false; other strings turn into true.
- Symbols turn into true.
- All objects become true.

> Note: A legacy behavior makes document.all return false when used as a boolean, despite it being an object. This property is legacy and non-standard and should not be used.

> Note: Unlike other type conversions like string coercion or number coercion, boolean coercion does not attempt to convert objects to primitives.

In other words, there are only a handful of values that get coerced to false — these are called **falsy** values. All other values are called **truthy** values. A value's truthiness is important when used with logical operators, conditional statements, or any boolean context.

There are two ways to achieve the same effect in JavaScript.

**Double NOT:** !!x negates x twice, which converts x to a boolean using the same algorithm as above.

**The Boolean() function:** Boolean(x) uses the same algorithm as above to convert x.

Note that truthiness is not the same as being loosely equal to true or false.

```
if ([]) {
  console.log("[] is truthy");
}
if ([] == false) {
  console.log("[] == false");
}
// [] is truthy
// [] == false

```

**Creating Boolean objects with an initial value of false**

```
const bNoParam = new Boolean(); // [Boolean: false]
const bZero = new Boolean(0); // [Boolean: false]
const bNull = new Boolean(null); // [Boolean: false]
const bEmptyString = new Boolean(""); // [Boolean: false]
const bfalse = new Boolean(false); // [Boolean: false]
```

**Creating Boolean objects with an initial value of true**
```
const btrue = new Boolean(true); // [Boolean: true]
const btrueString = new Boolean("true"); // [Boolean: true]
const bfalseString = new Boolean("false"); // [Boolean: true]
const bSuLin = new Boolean("Su Lin"); // [Boolean: true]
const bArrayProto = new Boolean([]); // [Boolean: true]
const bObjProto = new Boolean({}); // [Boolean: true]
```

## **Number type**

The number type represents both integer and floating point numbers.

JavaScript has only one type of number, which is a 64-bit floating-point number. This means that JavaScript numbers are always stored as double precision floating-point numbers, following the international IEEE 754 standard.

```
let x = 3.14;    // A number with decimals
let y = 3;       // A number without decimals
```
Extra large or extra small numbers can be written with scientific (exponent) notation:

```
let x = 123e5;    // 12300000
let y = 123e-5;   // 0.00123
```

**Integer Precision :-**

Integers (numbers without a period or exponent notation) are accurate up to 15 digits.

```
let x = 999999999999999;   
let y = 9999999999999999;   

console.log(x); // 999999999999999
console.log(y); // 10000000000000000
```

**Floating Precision :-**
Floating point arithmetic is not always 100% accurate:

```
let x = 0.2 + 0.1; 
console.log(x) // 0.30000000000000004

let y = (0.2*10 + 0.1*10) / 10;
console.log(y) //0.3
```
**Adding Numbers and Strings:-**

> **Note**-
JavaScript uses the **+** operator for both **addition **and **concatenation**.
**Numbers are added. Strings are concatenated.**

```
let x = 10;
let y = 20;
let z = x + y; // 30

let x = "10";
let y = "20";
let z = x + y;  // 1020
```
If you add a **number** and a **string**, the result will be a **string concatenation**:

```
let x = "10";
let y = 20;
let z = x + y; // 1020
```
**Note:-** A common mistake is to expect in this below result to be 30.

```
let x = 10;
let y = 20;
let z = "The result is: " + x + y; // The result is: 1020
```

**Note:-** A common mistake is to expect in this below result to be 102030:

```
let x = 10;
let y = 20;
let z = "30";
let result = x + y + z; // 3030
```

> **Note:-** 
The JavaScript **interpreter** works from **left to right**.
First 10 + 20 is added because x and y are both **numbers**.
Then 30 + "30" is concatenated because z is a **string**.


**Numeric Strings:-**

- JavaScript strings can have numeric content:

let x = 100;         // x is a number
let y = "100";       // y is a string

- JavaScript will try to **convert strings to numbers** in all **numeric operations**:

```
let x = "100";
let y = "10";
let z = x / y;
console.log(z) // 10
```

```
let x = "100";
let y = "10";
let z = x * y;
console.log(z) // 1000
```

```
let x = "100";
let y = "10";
let z = x - y;
console.log(z) // 90
```
The below will not work because JavaScript uses the **+** operator to **concatenate the strings**.

```
let x = "100";
let y = "10";
let z = x + y; //10010
```

**NaN - Not a Number:-**

- **NaN** is a JavaScript reserved word indicating that a number is **not a legal number**.
- Trying to do arithmetic with a non-numeric string will result in NaN (Not a Number):

```
let x = 100 / "Apple"; 
console.log(x) // Nan

However, if the string is numeric, the result will be a number:

let x = 100 / "10";
console.log(x) // 10
```

You can use the global JavaScript function **isNaN()** to find out if a value is a not a number:

```
let x = 100 / "Apple";
let y = isNaN(x);
console.log(y) // true
```
In the below example, If you use NaN in a mathematical operation, the result will also be **NaN**:
Or the result might be a concatenation like **NaN5**:

```
let x = NaN;
let y = 5;
let z = x + y;
console.log(z) // NaN

let x = NaN;
let y = "5";
let z = x + y;
console.log(z) // NaN5
```

- NaN is a number: typeof NaN returns number:

```
console.log(typeof NaN) // number
```

**Infinity :-**

Infinity (or -Infinity) is the value JavaScript will return if you calculate a number outside the largest possible number.

```
let myNumber = 2;
// Execute until Infinity
while (myNumber != Infinity) {
  myNumber = myNumber * myNumber;
}
console.log(myNumber) // Infinity
```

Division by 0 (zero) also generates **Infinity**:

```
let x =  2 / 0;
let y = -2 / 0;
```
**Note:-** -Infinity is a number: **typeof Infinity** returns number.

```
console.log(typeof Infinity) // number
```


**Hexadecimal:-**

JavaScript interprets numeric constants as hexadecimal if they are preceded by 0x.

```
let x = 0xFF;
console.log(x) // 255
```

> Never write a number with a leading zero (like 07).
Some JavaScript versions interpret numbers as octal if they are written with a leading zero.

- By default, JavaScript displays numbers as **base 10** decimals.
- But you can use the **toString()** method to output numbers from **base 2** to **base 36**.
- Hexadecimal is **base 16**. Decimal is **base 10**. Octal is **base 8**. Binary is **base 2**.

```
let myNumber = 32;
myNumber.toString(32);
myNumber.toString(16);
myNumber.toString(12);
myNumber.toString(10);
myNumber.toString(8);
myNumber.toString(2);
```


**JavaScript Numbers as Objects:-**

Normally JavaScript numbers are primitive values created from literals:

```
let x = 123;
let y = new Number(123);

console.log(x, y, typeof y) //123, [Number: 123], object
```

> 
- Do not create Number objects.
- The new keyword complicates the code and slows down execution speed.
- Number Objects can produce unexpected results:

```
let x = 500;
let y = new Number(500);
console.log(x == y) // true
console.log(x === y) // false

let a = new Number(500);
let b = new Number(500);

console.log(a == b) // true
console.log(a === b) // false
```

> Comparing two JavaScript objects always returns false.


## **BigInt type**

JavaScript BigInt variables are used to store big integer values that are too big to be represented by a normal JavaScript Number.


**JavaScript Integer Accuracy**

JavaScript integers are only accurate up to 15 digits:
let x = 999999999999999;
let y = 9999999999999999;

- In JavaScript, all numbers are stored in a 64-bit floating-point format (IEEE 754 standard).
- With this standard, large integer cannot be exactly represented and will be rounded.
- Because of this, JavaScript can only safely represent integers: Up to 9007199254740991 +(253-1) and Down to -9007199254740991 -(253-1).
- Integer values outside this range lose precision.

**How to Create a BigInt**

To create a BigInt, append n to the end of an integer or call BigInt():

```
let x = 9999999999999999;
let y = 9999999999999999n;

console.log(x) //10000000000000000
console.log(y) //9999999999999999n
```

```
let x = 1234567890123456789012345n;
let y = BigInt(1234567890123456789012345)

console.log(x) //1234567890123456789012345n
console.log(y) //1234567890123456824475648n
```

```
let x = BigInt(999999999999999);
let type = typeof x;

console.log(x) //999999999999999n
console.log(type) //bigint
```
the JavaScript **typeof a BigInt** is **"bigint"**:


## **String type**

A string in JavaScript must be surrounded by quotes.

```
let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed another ${str}`;
```
In JavaScript, there are 3 types of quotes.

1. Double quotes: "Hello".
2. Single quotes: 'Hello'.
3. Backticks: `Hello`.

> **Double** and **single quotes** are “simple” quotes. There’s practically no difference between them in JavaScript.

**Backticks** are “extended functionality” quotes. They allow us to embed variables and expressions into a string by wrapping them in ${…}, for example:

```
let name = "John";

// embed a variable
alert( `Hello, ${name}!` ); // Hello, John!

// embed an expression
alert( `the result is ${1 + 2}` ); // the result is 3
```
> The expression inside ${…} is evaluated and the result becomes a part of the string. We can put anything in there: a variable like name or an arithmetical expression like 1 + 2 or something more complex.

Please note that this can only be done in backticks. Other quotes don’t have this embedding functionality!

```
alert( "the result is ${1 + 2}" ); 
// the result is ${1 + 2} (double quotes do nothing)
```

**Template Strings:**

- Templates were introduced with ES6 (JavaScript 2016).
- Templates are strings enclosed in backticks (`This is a template string`).
- Templates allow single and double quotes inside a string:

```
let text = `He's often called "Johnny"`;
```
**String Length:**
To find the length of a string, use the built-in length property:

```
let text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let length = text.length; //26
```

**Escape Characters:**

Because strings must be written within quotes, JavaScript will misunderstand this string:

```
let text = "We are the so-called "Vikings" from the north.";
console.log(text);
// SyntaxError: Unexpected identifier
```

> To solve this problem, you can use an backslash escape character.
The backslash escape character (\) turns special characters into string characters:

Code	Result	Description
\'	'	Single quote
\"	"	Double quote
\\	\	Backslash

```
let text = "We are the so-called \"Vikings\" from the north.";
console.log(text); // We are the so-called "Vikings" from the north.

let text= 'It\'s alright.';
let text = "The character \\ is called backslash.";
```

- Six other escape sequences are valid in JavaScript:

Code	Result
\b	Backspace
\f	Form Feed
\n	New Line
\r	Carriage Return
\t	Horizontal Tabulator
\v	Vertical Tabulator

**JavaScript Strings as Objects:**

Normally, JavaScript strings are primitive values, created from literals:

strings can also be defined as objects with the keyword new:

```
let x = "John";
let y = new String("John");
```
Note:-

- Do not create Strings objects.
- The new keyword complicates the code and slows down execution speed.
- String objects can produce unexpected results:

```
let x = "John"; //john
let y = new String("John"); //[String: 'John']
console.log(x == y) //true
console.log(x === y) //false
console.log(typeof x) //string
console.log(typeof y) //object
```

```
let x = new String("John");
let y = new String("John");
console.log(x == y) //false
console.log(x === y) //false
console.log(typeof y) //object
```

## **Symbol type**

A Symbol is a unique and immutable primitive value and may be used as the key of an Object property (see below). In some programming languages, Symbols are called "atoms". The purpose of symbols is to create unique property keys that are guaranteed not to clash with keys from other code.

To create a new primitive Symbol, you write Symbol() with an optional string as its description:

```
const sym1 = Symbol();
const sym2 = Symbol("foo");
const sym3 = Symbol("foo");

console.log(sym1) //Symbol()
console.log(sym2) //Symbol(foo)
console.log(sym3) //Symbol(foo)
```

> The above code creates three new Symbols. Note that Symbol("foo") does not coerce the string "foo" into a Symbol. It creates a new Symbol each time:

```
const sym2 = Symbol("foo");
const sym3 = Symbol("foo");

console.log(sym2 === sym3) // false
console.log(sym2 == sym3) //false
```

**Note:-** 
Symbols are the only primitive data type that has reference identity (that is, you cannot create the same symbol twice).

```
const sym = Symbol("foo");
typeof sym; // "symbol"
```