JavaScript Variables and Data Types
Understanding variables and data types is fundamental to mastering JavaScript. Variables store data values, while data types define what kind of data can be stored and manipulated. This comprehensive tutorial covers everything you need to know.
What are Variables?
Variables are containers that store data values. Think of them as labeled boxes where you can keep information that your program can use and modify. JavaScript variables are dynamically typed, meaning you don’t have to declare the data type explicitly.
Declaring Variables in JavaScript
JavaScript provides three ways to declare variables:
| Keyword | Scope | Can Reassign? | Can Redeclare? | Hoisting |
|---|---|---|---|---|
| let | Block-scoped | Yes | No | Temporal Dead Zone |
| const | Block-scoped | No (constant) | No | Temporal Dead Zone |
| var | Function-scoped | Yes | Yes | Hoisted (undefined) |
1. Using let (Modern, Recommended)
// Declaring variables with let
let name = "John";
let age = 25;
let isStudent = true;
// Can be reassigned
name = "Jane"; // โ Allowed
age = 26; // โ Allowed
// Cannot be redeclared in same scope
// let name = "Bob"; // โ Error: Identifier 'name' has already been declared
2. Using const (Constants)
// Declaring constants
const PI = 3.14159;
const BIRTH_YEAR = 1995;
const COMPANY_NAME = "Tech Corp";
// Cannot be reassigned
// PI = 3.14; // โ Error: Assignment to constant variable
// Must be initialized at declaration
// const COLOR; // โ Error: Missing initializer
Note: For objects and arrays declared with
const, you can modify the contents, but you cannot reassign the variable itself.
const person = { name: "John", age: 30 };
person.age = 31; // โ Allowed (modifying property)
person.city = "NYC"; // โ Allowed (adding property)
// person = {}; // โ Error: Cannot reassign
3. Using var (Old Way, Avoid in Modern JS)
// var is function-scoped
var oldWay = "discouraged";
var oldWay = "can redeclare"; // โ Allowed but problematic
// var has function scope, not block scope
if (true) {
var x = 10; // Function-scoped
}
console.log(x); // 10 (accessible outside block!)
Variable Naming Rules
Follow these rules when naming variables:
- Names can contain letters, digits, underscores (_), and dollar signs ($)
- Names must begin with a letter, underscore, or dollar sign
- Names are case-sensitive (
myVarโmyvar) - Reserved keywords cannot be used (like
if,for,while)
Valid Variable Names:
let userName = "John";
let _private = "hidden";
let $money = 100;
let firstName23 = "Alex";
let camelCase = "recommended";
let PascalCase = "for classes";
let snake_case = "valid but not common";
Invalid Variable Names:
// let 123name = "invalid"; // Cannot start with number
// let my-name = "invalid"; // Hyphen not allowed
// let user name = "invalid"; // Spaces not allowed
// let let = "invalid"; // Reserved keyword
JavaScript Data Types
JavaScript has 8 data types divided into two categories: Primitive and Non-Primitive (Reference).
Primitive Data Types
| Type | Description | Example |
|---|---|---|
| Number | Integers and floating-point numbers | let age = 25; let price = 99.99; |
| String | Text data enclosed in quotes | let name = "John"; let char = 'A'; |
| Boolean | true or false values | let isActive = true; let done = false; |
| Undefined | Variable declared but not assigned | let x; console.log(x); // undefined |
| Null | Intentional absence of value | let empty = null; |
| BigInt | Large integers beyond Number limit | let big = 9007199254740991n; |
| Symbol | Unique immutable identifiers | let sym = Symbol('id'); |
Non-Primitive (Reference) Data Types
| Type | Description | Example |
|---|---|---|
| Object | Collection of key-value pairs | let person = {name: "John", age: 30}; |
| Array | Ordered list of values | let colors = ["red", "green", "blue"]; |
| Function | Reusable block of code | function greet() { return "Hello"; } |
| Date | Date and time objects | let now = new Date(); |
| RegExp | Regular expressions for pattern matching | let pattern = /ab+c/; |
Detailed Look at Each Data Type
1. Number
JavaScript numbers are always stored as double-precision floating-point numbers (64-bit).
// Integers
let age = 25;
let year = 2024;
// Floating-point numbers
let price = 99.99;
let temperature = -5.6;
// Special numeric values
let infinity = Infinity;
let negativeInfinity = -Infinity;
let notANumber = NaN; // Result of invalid math operation
// Number methods
let num = 123.456;
console.log(num.toFixed(2)); // "123.46"
console.log(num.toPrecision(4)); // "123.5"
// Converting to number
let str = "123";
let converted = Number(str); // 123
let parsed = parseInt("123px"); // 123
let floatParsed = parseFloat("123.45px"); // 123.45
2. String
Strings represent textual data and can be created using single quotes, double quotes, or backticks.
// Three ways to create strings
let single = 'Hello';
let double = "World";
let backtick = `Template Literal`;
// String concatenation
let firstName = "John";
let lastName = "Doe";
let fullName = firstName + " " + lastName; // "John Doe"
// Template literals (string interpolation)
let age1 = 25;
let message = `My name is ${firstName} and I am ${age1} years old.`;
console.log(message); // "My name is John and I am 25 years old."
// String methods
let text = "JavaScript is awesome!";
console.log(text.length); // 22
console.log(text.toUpperCase()); // "JAVASCRIPT IS AWESOME!"
console.log(text.toLowerCase()); // "javascript is awesome!"
console.log(text.indexOf("Script")); // 4
console.log(text.includes("Java")); // true
console.log(text.slice(0, 10)); // "JavaScript"
console.log(text.split(" ")); // ["JavaScript", "is", "awesome!"]
// Escape sequences
let escaped = "She said, \"Hello!\"";
let newLine = "First line\nSecond line";
let tab = "Column1\tColumn2";
3. Boolean
Booleans represent logical values: true or false.
let isLoggedIn = true;
let hasPermission = false;
// Comparison operations return booleans
let isEqual = (5 === 5); // true
let isGreater = (10 > 5); // true
let isLess = (3 < 1); // false
// Logical operators with booleans
let andResult = true && false; // false
let orResult = true || false; // true
let notResult = !true; // false
// Truthy and Falsy values
// Falsy values: false, 0, "" (empty string), null, undefined, NaN
// Everything else is truthy
if ("Hello") {
console.log("This runs because string is truthy");
}
if (0) {
console.log("This won't run because 0 is falsy");
}
4. Undefined
A variable that has been declared but not assigned a value is undefined.
let x;
console.log(x); // undefined
let y = undefined; // You can explicitly set to undefined, but not recommended
// Checking if a variable is undefined
if (typeof x === "undefined") {
console.log("x is undefined");
}
5. Null
null represents the intentional absence of any object value.
let emptyValue = null; // Explicitly set to have no value
// Difference between undefined and null
let notAssigned; // undefined
let assignedNull = null; // null
console.log(typeof null); // "object" (this is a historical bug in JavaScript)
// Checking for null
if (assignedNull === null) {
console.log("Value is null");
}
6. BigInt
Used for integers larger than 2โตยณ - 1 (Number.MAX_SAFE_INTEGER).
// Creating BigInt
let bigNumber = 9007199254740991n; // Add 'n' at the end
let anotherBig = BigInt(9007199254740991);
// Operations with BigInt
let sum = 10n + 20n; // 30n
let product = 5n * 3n; // 15n
// Cannot mix BigInt with regular numbers
// let result = 10n + 5; // Error!
// Comparison works
console.log(10n === 10); // false (different types)
console.log(10n == 10); // true (abstract equality)
7. Symbol
Symbols are unique and immutable primitive values, often used as object property keys.
// Creating symbols
let sym1 = Symbol("id");
let sym2 = Symbol("id");
console.log(sym1 === sym2); // false (each symbol is unique)
// Using symbols as object keys
const uniqueKey = Symbol("unique");
let obj = {
[uniqueKey]: "hidden value",
regularKey: "normal value"
};
console.log(obj[uniqueKey]); // "hidden value"
// Symbol keys are not enumerated in for...in loops
8. Object
Objects are collections of key-value pairs (properties).
// Creating objects
let person = {
firstName: "John",
lastName: "Doe",
age: 30,
email: "john@example.com",
isActive: true,
// Object method
getFullName: function() {
return this.firstName + " " + this.lastName;
}
};
// Accessing properties
console.log(person.firstName); // "John" (dot notation)
console.log(person["lastName"]); // "Doe" (bracket notation)
console.log(person.getFullName()); // "John Doe"
// Adding/updating properties
person.city = "New York";
person.age = 31;
// Deleting properties
delete person.email;
// Checking if property exists
console.log("age" in person); // true
console.log(person.hasOwnProperty("city")); // true
// Object methods
let keys = Object.keys(person); // ["firstName", "lastName", "age", ...]
let values = Object.values(person); // ["John", "Doe", 31, ...]
let entries = Object.entries(person); // [["firstName","John"], ...]
// Object destructuring
let { firstName, age: personAge } = person;
console.log(firstName); // "John"
console.log(personAge); // 31
9. Array
Arrays are ordered lists of values (special type of object).
// Creating arrays
let colors = ["red", "green", "blue"];
let numbers = new Array(1, 2, 3, 4, 5);
let mixed = [1, "text", true, null, {name: "object"}]; // Mixed types
// Accessing elements (0-indexed)
console.log(colors[0]); // "red"
console.log(colors[2]); // "blue"
console.log(colors.length); // 3
// Modifying arrays
colors[1] = "yellow"; // ["red", "yellow", "blue"]
colors.push("purple"); // Add to end: ["red", "yellow", "blue", "purple"]
colors.pop(); // Remove from end: ["red", "yellow", "blue"]
colors.unshift("orange"); // Add to beginning: ["orange", "red", "yellow", "blue"]
colors.shift(); // Remove from beginning: ["red", "yellow", "blue"]
// Array methods
let fruits = ["apple", "banana", "orange"];
console.log(fruits.indexOf("banana")); // 1
console.log(fruits.includes("grape")); // false
let sliced = fruits.slice(1, 3); // ["banana", "orange"]
let joined = fruits.join(", "); // "apple, banana, orange"
// Array iteration
fruits.forEach(function(fruit) {
console.log(fruit);
});
// Modern array methods
let numbers1 = [1, 2, 3, 4, 5];
let doubled = numbers1.map(n => n * 2); // [2, 4, 6, 8, 10]
let evens = numbers1.filter(n => n % 2 === 0); // [2, 4]
let sum = numbers1.reduce((acc, n) => acc + n, 0); // 15
// Array destructuring
let [first, second] = colors;
console.log(first); // "red"
console.log(second); // "yellow"
10. Function
Functions are reusable blocks of code (also treated as objects).
// Function declaration
function greet(name) {
return `Hello, ${name}!`;
}
// Function expression
const add = function(a, b) {
return a + b;
};
// Arrow function (modern)
const multiply = (a, b) => a * b;
const sayHello = () => console.log("Hello");
// Functions with default parameters
function power(base, exponent = 2) {
return base ** exponent;
}
console.log(power(5)); // 25
console.log(power(2, 3)); // 8
// Rest parameters
function sumAll(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sumAll(1, 2, 3, 4, 5)); // 15
// Immediately Invoked Function Expression (IIFE)
(function() {
console.log("Runs immediately");
})();
// Function as object method
const calculator = {
add(a, b) {
return a + b;
}
};
console.log(calculator.add(5, 3)); // 8
Type Conversion and Coercion
Explicit Conversion (Type Casting)
// Convert to String
let num = 123;
let str1 = String(num); // "123"
let str2 = num.toString(); // "123"
// Convert to Number
let str = "456";
let num1 = Number(str); // 456
let num2 = parseInt("123.45"); // 123
let num3 = parseFloat("123.45"); // 123.45
let num4 = +str; // 456 (unary plus operator)
// Convert to Boolean
let value = "hello";
let bool1 = Boolean(value); // true
let bool2 = !!value; // true (double NOT operator)
Implicit Coercion (Automatic)
// String coercion
let result = "5" + 3; // "53" (number coerced to string)
let result2 = "5" - 3; // 2 (string coerced to number)
// Boolean coercion in conditions
if ("hello") { // "hello" is truthy
console.log("Runs");
}
if (0) { // 0 is falsy
console.log("Doesn't run");
}
// Comparison coercion
console.log(5 == "5"); // true (string converted to number)
console.log(5 === "5"); // false (no coercion, different types)
Checking Data Types
Using typeof Operator
console.log(typeof 42); // "number"
console.log(typeof "Hello"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (bug in JavaScript)
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof function(){}); // "function"
// Checking for array
let arr = [1, 2, 3];
console.log(Array.isArray(arr)); // true
// Checking for null
let val = null;
console.log(val === null); // true
// More precise checking
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call({})); // "[object Object]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
Variable Scope
Global Scope
let globalVar = "I'm global";
function testFunction() {
console.log(globalVar); // Accessible
}
console.log(globalVar); // Accessible
Function Scope
function myFunction() {
var functionScoped = "Only inside function";
let blockScoped = "Also only inside";
console.log(functionScoped); // Accessible
}
// console.log(functionScoped); // Error: Not defined
Block Scope (let and const)
if (true) {
let blockVar = "Only in this block";
const blockConst = "Also only in block";
var varVar = "Function scoped, not block scoped";
console.log(blockVar); // Accessible
}
// console.log(blockVar); // Error: Not defined
console.log(varVar); // Accessible (var is not block-scoped)
Hoisting in JavaScript
Hoisting is JavaScript's behavior of moving declarations to the top of their scope.
// var hoisting
console.log(myVar); // undefined (not an error)
var myVar = 5;
// let and const hoisting (Temporal Dead Zone)
// console.log(myLet); // ReferenceError
let myLet = 10;
// Function hoisting
sayHello(); // Works! Function declarations are hoisted
function sayHello() {
console.log("Hello!");
}
// Function expressions are not hoisted
// sayHi(); // Error
const sayHi = function() {
console.log("Hi!");
};
Best Practices
- Use const by default - Only use let when you need to reassign
- Avoid var - Use let and const for better scoping
- Use meaningful variable names - Names should describe what they store
- Use camelCase for variables - Standard convention in JavaScript
- Initialize variables when declaring - Avoid undefined states
- Use === instead of == - Avoid unexpected type coercion
- Declare variables at the top of their scope - Improves readability
Practical Examples
Example 1: User Profile
// User profile object
const userProfile = {
username: "js_learner",
email: "learner@example.com",
age: 25,
isPremium: false,
skills: ["JavaScript", "HTML", "CSS"],
getInfo() {
return `${this.username} (${this.email}) - ${this.age} years old`;
},
addSkill(skill) {
this.skills.push(skill);
}
};
console.log(userProfile.getInfo());
userProfile.addSkill("React");
console.log(userProfile.skills);
Example 2: Temperature Converter
function convertTemperature(celsius) {
const fahrenheit = (celsius * 9/5) + 32;
const kelvin = celsius + 273.15;
return {
celsius: celsius,
fahrenheit: fahrenheit,
kelvin: kelvin
};
}
let temp = convertTemperature(25);
console.log(`${temp.celsius}ยฐC = ${temp.fahrenheit}ยฐF = ${temp.kelvin}K`);
Example 3: Shopping Cart
// Shopping cart using array of objects
let cart = [];
function addItem(name, price, quantity = 1) {
cart.push({
name: name,
price: price,
quantity: quantity
});
}
function calculateTotal() {
return cart.reduce((total, item) => total + (item.price * item.quantity), 0);
}
addItem("Laptop", 999.99, 1);
addItem("Mouse", 29.99, 2);
addItem("Keyboard", 79.99, 1);
console.log(`Total: $${calculateTotal().toFixed(2)}`);
Quick Reference Summary
Variable Declaration
let variable = value;- Mutable, block-scopedconst CONSTANT = value;- Immutable, block-scopedvar old = value;- Avoid using
Primitive Data Types
Number- Integer or floating-pointString- Text dataBoolean- true/falseUndefined- Not assigned a valueNull- Intentional absenceBigInt- Large integersSymbol- Unique identifier
Reference Data Types
Object- Key-value pairsArray- Ordered listFunction- Reusable code block
Type Checking
typeof value- Returns type stringArray.isArray(value)- Checks if arrayvalue === null- Checks for null
Pro Tip: Always use
constas your default choice. Only useletwhen you know the variable needs to be reassigned. Never usevarin modern JavaScript code!
Next Steps
- Practice creating and manipulating different data types
- Learn about type coercion and when it happens
- Master array and object methods
- Study JavaScript control flow (conditions and loops)
- Explore functions in depth (closures, callbacks, promises)