Primitive Data Types


Primitive Data Types: The immutable core values.

Primitive data types in JavaScript are the fundamental, immutable values that are not objects. They are the building blocks for more complex data structures and are stored directly in the variable. Understanding these core types is essential for effective JavaScript programming.


string: Textual data. Template literals (backticks - ES6+) for interpolation and multi-line strings.

A string is a sequence of characters used to represent text. You can create strings using single quotes, double quotes, or backticks for template literals, which allow for embedded expressions and multi-line strings.

Example 1: Basic String Creation

// Using double quotes to create a string.
const greeting = "Hello, World!";
console.log(greeting); // Outputs: Hello, World!

Explanation

This code declares a constant variable greeting and assigns it the string value "Hello, World!". The console.log() function then displays this string in the console.


Example 2: Using Template Literals

// Using backticks for template literals.
const name = "Alice";
const message = `Hello, ${name}!`;
console.log(message); // Outputs: Hello, Alice!

Explanation

This example demonstrates a template literal. The value of the name variable is embedded directly into the string using the ${} syntax, creating a personalized message.


Example 3: Multi-line Strings

// Creating a multi-line string using backticks.
const multiLine = `This is a string
that spans across
multiple lines.`;
console.log(multiLine);

Explanation

Backticks make creating multi-line strings simple and readable without needing special characters. The string is outputted with the line breaks preserved.


Example 4: String Concatenation

// Combining strings using the + operator.
const firstName = "John";
const lastName = "Doe";
const fullName = firstName + " " + lastName;
console.log(fullName); // Outputs: John Doe

Explanation

This code concatenates, or joins, three strings together to form a full name. The + operator is used to combine the firstName, a space, and the lastName.


Example 5: String Properties and Methods

// Using the length property and toUpperCase() method.
const text = "javascript";
console.log(text.length); // Outputs: 10
console.log(text.toUpperCase()); // Outputs: JAVASCRIPT

Explanation

Strings have built-in properties and methods. The .length property returns the number of characters in the string, and the .toUpperCase() method returns a new string with all characters in uppercase.

number: IEEE 754 floating-point standard. Integers, floats, NaN (Not-a-Number), Infinity, -Infinity. Precision considerations.

The number type in JavaScript represents both integer and floating-point numbers. It also includes special values like NaN, Infinity, and -Infinity and is based on the IEEE 754 standard, which can lead to precision issues with floating-point arithmetic.

Example 1: Integer and Float

// Demonstrating integer and floating-point numbers.
let integerVar = 42;
let floatVar = 3.14;
console.log(integerVar); // Outputs: 42
console.log(floatVar); // Outputs: 3.14

Explanation

This code shows the declaration of two number variables: one holding an integer and the other a floating-point value. Both are of the number data type.


Example 2: Arithmetic Operations

// Performing basic arithmetic.
let x = 10;
let y = 5;
let sum = x + y;
let product = x * y;
console.log(sum); // Outputs: 15
console.log(product); // Outputs: 50

Explanation

This demonstrates simple arithmetic operations. The variables x and y are added and multiplied, with the results stored in the sum and product variables respectively.


Example 3: NaN - Not-a-Number

// Resulting in NaN from an invalid operation.
let result = 0 / 0;
console.log(result); // Outputs: NaN

Explanation

NaN is a special numeric value that represents an undefined or unrepresentable value resulting from an arithmetic operation, such as dividing zero by zero.


Example 4: Infinity

// Operations resulting in Infinity.
let positiveInfinity = 1 / 0;
let negativeInfinity = -1 / 0;
console.log(positiveInfinity); // Outputs: Infinity
console.log(negativeInfinity); // Outputs: -Infinity

Explanation

Dividing a non-zero number by zero results in Infinity or -Infinity, depending on the sign of the numerator. These are special numeric values in JavaScript.


Example 5: Precision Issues

// Demonstrating a floating-point precision issue.
let a = 0.1;
let b = 0.2;
let c = a + b;
console.log(c); // Outputs: 0.30000000000000004

Explanation

This example highlights a common issue with floating-point math in JavaScript. Due to how these numbers are stored in binary, the result is not exactly 0.3.

boolean: true or false. The basis of all logic.

The boolean data type is fundamental to programming and represents one of two values: true or false. Booleans are essential for conditional statements and control flow in your code.

Example 1: Basic Boolean Variables

// Declaring and assigning boolean values.
let isJavaScriptFun = true;
let isFishFlying = false;
console.log(isJavaScriptFun); // Outputs: true
console.log(isFishFlying); // Outputs: false

Explanation

This code declares two variables and assigns them the boolean values true and false respectively. These represent the truthiness or falsiness of a condition.


Example 2: Boolean in a Conditional

// Using a boolean in an if statement.
let hasLoggedIn = true;
if (hasLoggedIn) {
  console.log("Welcome!"); // This will be executed.
}

Explanation

The if statement checks the value of hasLoggedIn. Since it is true, the code block inside the if statement is executed.


Example 3: Comparison Operators

// Using comparison operators to produce a boolean.
let age = 20;
let isAdult = age >= 18;
console.log(isAdult); // Outputs: true

Explanation

The greater than or equal to operator (>=) compares age to 18. The result of this comparison is a boolean value, which is then stored in the isAdult variable.


Example 4: Logical Operators

// Using logical AND (&&) operator.
let hasUsername = true;
let hasPassword = false;
let canLogin = hasUsername && hasPassword;
console.log(canLogin); // Outputs: false

Explanation

The logical AND operator (&&) returns true only if both operands are true. In this case, since hasPassword is false, canLogin becomes false.


Example 5: Falsy Values

// Demonstrating a falsy value in a boolean context.
let emptyString = "";
if (emptyString) {
  console.log("This will not be printed.");
} else {
  console.log("The string is empty and therefore falsy.");
}

Explanation

In JavaScript, certain values like an empty string, 0, null, undefined, and NaN are "falsy". This means they behave like false in a boolean context.

undefined: A variable declared but not yet assigned a value.

A variable that has been declared but not assigned a value has the value undefined. It is a primitive value automatically assigned by JavaScript in this situation.

Example 1: Unassigned Variable

// A variable declared without a value is undefined.
let user;
console.log(user); // Outputs: undefined

Explanation

The variable user is declared, but no value is assigned to it. Therefore, its value is undefined by default.


Example 2: Function with No Return

// A function that doesn't return a value returns undefined.
function greet() {
  // No return statement
}
console.log(greet()); // Outputs: undefined

Explanation

The greet function does not have a return statement. When this function is called, it implicitly returns undefined.


Example 3: Accessing Non-existent Property

// Accessing an object property that doesn't exist.
const person = {
  name: "Jane"
};
console.log(person.age); // Outputs: undefined

Explanation

The person object does not have an age property. Attempting to access a non-existent property on an object results in undefined.


Example 4: Explicitly Setting to undefined

// Intentionally setting a variable to undefined.
let city = "Seattle";
city = undefined; // Not a common practice
console.log(city); // Outputs: undefined

Explanation

While possible, it is generally not recommended to explicitly assign undefined. null is preferred for intentionally indicating an absence of value.


Example 5: Checking for undefined

// Using the typeof operator to check for undefined.
let car;
if (typeof car === 'undefined') {
  console.log("The car variable is undefined.");
}

Explanation

The typeof operator is a reliable way to check if a variable's type is undefined. This is useful for verifying if a variable has been initialized.

null: Intentional absence of any object value. The difference between null and undefined.

The null value represents the intentional absence of any object value. It is a primitive value that developers can assign to a variable to signify that it holds no value, which is different from undefined, which is an automatic assignment for uninitialized variables.

Example 1: Assigning null

// Explicitly assigning null to a variable.
let selectedProduct = null;
console.log(selectedProduct); // Outputs: null

Explanation

Here, selectedProduct is intentionally set to null to indicate that no product has been selected yet. This is a common use case for null.


Example 2: null vs. undefined

// Demonstrating the difference between null and undefined.
let uninitializedVar; // undefined
let emptyVar = null; // null
console.log(typeof uninitializedVar); // "undefined"
console.log(typeof emptyVar); // "object" (a known quirk in JS)

Explanation

uninitializedVar is undefined because it was never assigned a value. emptyVar is explicitly null. Note that typeof null returning "object" is a long-standing bug in JavaScript.


Example 3: Resetting an Object

// Using null to clear the value of an object.
let userProfile = { name: "Sam" };
userProfile = null; // The object is no longer accessible
console.log(userProfile); // Outputs: null

Explanation

Assigning null to userProfile effectively clears its content and can make the original object eligible for garbage collection, freeing up memory.


Example 4: Loose Equality of null and undefined

// null and undefined are loosely equal.
console.log(null == undefined); // Outputs: true

Explanation

The loose equality operator (==) considers null and undefined to be equal. This is because both represent a lack of value in a similar, though not identical, way.


Example 5: Strict Equality of null and undefined

// null and undefined are not strictly equal.
console.log(null === undefined); // Outputs: false

Explanation

The strict equality operator (===) checks for both value and type. Since null and undefined are of different types, they are not strictly equal.

symbol (ES6+): Unique identifiers, useful for object properties.

Introduced in ECMAScript 2015 (ES6), the symbol data type produces unique and immutable primitive values. They are often used as unique keys for object properties to avoid naming collisions.

Example 1: Creating a Symbol

// Creating a new symbol.
const id = Symbol();
console.log(id); // Outputs: Symbol()

Explanation

The Symbol() function creates a new, unique symbol every time it is called. The value it produces is guaranteed to be unique.


Example 2: Symbol with a Description

// Creating a symbol with a descriptive string.
const id1 = Symbol("id");
const id2 = Symbol("id");
console.log(id1 === id2); // Outputs: false

Explanation

Even with the same description, each symbol created is unique. The description is primarily for debugging purposes and does not affect the uniqueness of the symbol.


Example 3: Symbols as Object Keys

// Using a symbol as a key for an object property.
const user_id = Symbol("user_id");
let user_obj = {
  name: "Ken",
  [user_id]: 12345
};
console.log(user_obj[user_id]); // Outputs: 12345

Explanation

To use a symbol as an object property key, you must use square bracket notation. This allows for the creation of "hidden" properties that won't clash with other property names.


Example 4: Symbols are not Enumerable

// Symbol properties are not included in for...in loops.
const secret = Symbol("secret");
let obj = {
  name: "Top Secret",
  [secret]: "This is a secret message."
};

for (let key in obj) {
  console.log(key); // Outputs: name
}

Explanation

Properties with symbol keys are not enumerated in for...in loops or with Object.keys(). This helps in creating properties that are not meant to be iterated over in standard ways.


Example 5: Global Symbols

// Using the global symbol registry.
const globalSym1 = Symbol.for("app.id");
const globalSym2 = Symbol.for("app.id");
console.log(globalSym1 === globalSym2); // Outputs: true

Explanation

Symbol.for() creates a symbol in a global registry. If a symbol with the given key already exists, it is returned; otherwise, a new one is created. This allows for sharing symbols across different parts of an application.

bigint (ES2020+): For arbitrarily large integers. When number just isn't big enough.

Introduced in ECMAScript 2020, bigint is a numeric primitive type that can represent integers with arbitrary precision. This is useful for working with numbers that are larger than the maximum safe integer limit of the number type.

Example 1: Creating a BigInt

// Creating a BigInt by appending 'n' to an integer.
const largeNumber = 9007199254740991n;
const anotherLargeNumber = BigInt(9007199254740992);
console.log(largeNumber);
console.log(anotherLargeNumber);

Explanation

You can create a bigint by either appending n to the end of an integer literal or by calling the BigInt() constructor. Both methods produce a bigint value.


Example 2: Arithmetic with BigInts

// Performing arithmetic with BigInts.
const a_big = 10n;
const b_big = 20n;
const sum_big = a_big + b_big;
console.log(sum_big); // Outputs: 30n
console.log(typeof sum_big); // "bigint"

Explanation

Arithmetic operators like +, -, *, and / work with bigint values. The result of such an operation is also a bigint.


Example 3: Cannot Mix BigInt and Number

// Attempting to mix BigInt and Number types in an operation.
try {
  const result = 10n + 5;
} catch (error) {
  console.error(error); // TypeError: Cannot mix BigInt and other types
}

Explanation

You cannot perform arithmetic operations between a bigint and a number. This will result in a TypeError. You must explicitly convert one of the types.


Example 4: Comparison of BigInt and Number

// Comparing a BigInt and a Number.
console.log(10n == 10); // Outputs: true
console.log(10n === 10); // Outputs: false

Explanation

The loose equality operator (==) will consider a bigint and a number with the same value as equal. However, the strict equality operator (===) will return false because they are of different types.


Example 5: BigInt Division

// Division with BigInts results in an integer.
const dividend = 7n;
const divisor = 2n;
const quotient = dividend / divisor;
console.log(quotient); // Outputs: 3n

Explanation

When dividing bigints, the result is truncated to an integer, and any fractional part is discarded. There are no fractional bigints.