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 bigint
s, the result is truncated to an integer, and any fractional part is discarded. There are no fractional bigint
s.