JavaScript Objects & Arrays
Objects and arrays are fundamental data structures in JavaScript. Objects store collections of data as key-value pairs, while arrays store ordered collections of values. Understanding how to work with these structures is essential for effective JavaScript programming.
JavaScript Objects
Objects in JavaScript are collections of key-value pairs, where each key is a string (or Symbol) and each value can be any data type, including other objects.
Creating Objects
// Object literal notation
const person = {
firstName: "John",
lastName: "Doe",
age: 30,
email: "john.doe@example.com",
isEmployed: true,
hobbies: ["reading", "swimming", "coding"]
};
// Empty object
const emptyObject = {};
// Using the Object constructor
const anotherObject = new Object();
anotherObject.property = "value";
Accessing Object Properties
// Dot notation
console.log(person.firstName); // "John"
console.log(person.age); // 30
// Bracket notation
console.log(person["lastName"]); // "Doe"
// Bracket notation is useful when property names are dynamic
const propertyName = "email";
console.log(person[propertyName]); // "john.doe@example.com"
// Accessing nested properties
console.log(person.hobbies[0]); // "reading"
Modifying Objects
// Adding new properties
person.address = "123 Main St";
person["phoneNumber"] = "555-1234";
// Modifying existing properties
person.age = 31;
person["isEmployed"] = false;
// Deleting properties
delete person.email;
// Checking if a property exists
console.log("firstName" in person); // true
console.log("middleName" in person); // false
// hasOwnProperty method
console.log(person.hasOwnProperty("age")); // true
Object Methods
// Adding methods to objects
const calculator = {
add: function(a, b) {
return a + b;
},
// Shorthand method syntax (ES6)
subtract(a, b) {
return a - b;
},
// Arrow function as method (note: different 'this' behavior)
multiply: (a, b) => a * b
};
console.log(calculator.add(5, 3)); // 8
console.log(calculator.subtract(10, 4)); // 6
console.log(calculator.multiply(2, 6)); // 12
The 'this' Keyword in Objects
const person = {
firstName: "John",
lastName: "Doe",
// Regular function as method
getFullName: function() {
return this.firstName + " " + this.lastName;
},
// Arrow function doesn't have its own 'this'
getArrowFullName: () => {
// 'this' refers to the outer scope, not the person object
return this.firstName + " " + this.lastName; // Will not work as expected
}
};
console.log(person.getFullName()); // "John Doe"
console.log(person.getArrowFullName()); // "undefined undefined" (or error)
Warning: Arrow functions don't have their own this
context. When used as object methods, they inherit this
from the surrounding scope, which is usually not what you want. Use regular functions for object methods when you need to access the object with this
.
Object Destructuring (ES6)
const person = {
firstName: "John",
lastName: "Doe",
age: 30,
address: {
street: "123 Main St",
city: "Anytown",
country: "USA"
}
};
// Basic destructuring
const { firstName, lastName } = person;
console.log(firstName); // "John"
console.log(lastName); // "Doe"
// Destructuring with new variable names
const { firstName: fName, lastName: lName } = person;
console.log(fName); // "John"
console.log(lName); // "Doe"
// Nested destructuring
const { address: { city, country } } = person;
console.log(city); // "Anytown"
console.log(country); // "USA"
// Default values
const { middleName = "N/A" } = person;
console.log(middleName); // "N/A" (since it doesn't exist in person)
Object Methods from Object.prototype
const person = {
firstName: "John",
lastName: "Doe",
age: 30
};
// Check if property exists
console.log(person.hasOwnProperty("firstName")); // true
console.log(person.hasOwnProperty("toString")); // false (inherited)
// Convert to string
console.log(person.toString()); // "[object Object]"
// Get property names
console.log(Object.keys(person)); // ["firstName", "lastName", "age"]
// Get property values
console.log(Object.values(person)); // ["John", "Doe", 30]
// Get key-value pairs as arrays
console.log(Object.entries(person));
// [['firstName', 'John'], ['lastName', 'Doe'], ['age', 30]]
Object.assign and Spread Operator
// Copying objects with Object.assign
const person = { firstName: "John", lastName: "Doe" };
const details = { age: 30, job: "Developer" };
// Merge objects
const merged = Object.assign({}, person, details);
console.log(merged);
// { firstName: "John", lastName: "Doe", age: 30, job: "Developer" }
// Spread operator (ES6)
const mergedWithSpread = { ...person, ...details };
console.log(mergedWithSpread);
// { firstName: "John", lastName: "Doe", age: 30, job: "Developer" }
// Creating a copy with modifications
const updatedPerson = { ...person, age: 31, firstName: "Jane" };
console.log(updatedPerson);
// { firstName: "Jane", lastName: "Doe", age: 31 }
Note: Both Object.assign
and the spread operator create shallow copies. Nested objects are still referenced, not duplicated.
JavaScript Arrays
Arrays in JavaScript are ordered collections of values. They can store values of any type, including other arrays and objects.
Creating Arrays
// Array literal notation
const fruits = ["apple", "banana", "orange"];
// Empty array
const emptyArray = [];
// Array with mixed types
const mixed = [1, "hello", true, { name: "John" }, [1, 2, 3]];
// Using the Array constructor
const numbers = new Array(1, 2, 3, 4, 5);
// Creating an array with a specific length
const zeros = new Array(5); // Creates an array with 5 empty slots
Accessing Array Elements
const fruits = ["apple", "banana", "orange", "mango"];
// Using index (zero-based)
console.log(fruits[0]); // "apple"
console.log(fruits[2]); // "orange"
// Getting the last element
console.log(fruits[fruits.length - 1]); // "mango"
// Using at() method (ES2022)
console.log(fruits.at(-1)); // "mango" (last element)
console.log(fruits.at(-2)); // "orange" (second-to-last element)
// Accessing elements in nested arrays
const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
console.log(matrix[1][2]); // 6
Modifying Arrays
const fruits = ["apple", "banana", "orange"];
// Changing an element
fruits[1] = "grape";
console.log(fruits); // ["apple", "grape", "orange"]
// Adding elements to the end
fruits.push("mango");
console.log(fruits); // ["apple", "grape", "orange", "mango"]
// Adding elements to the beginning
fruits.unshift("pear");
console.log(fruits); // ["pear", "apple", "grape", "orange", "mango"]
// Removing the last element
const lastFruit = fruits.pop();
console.log(lastFruit); // "mango"
console.log(fruits); // ["pear", "apple", "grape", "orange"]
// Removing the first element
const firstFruit = fruits.shift();
console.log(firstFruit); // "pear"
console.log(fruits); // ["apple", "grape", "orange"]
// Removing elements at a specific position
const removed = fruits.splice(1, 1); // Remove 1 element at index 1
console.log(removed); // ["grape"]
console.log(fruits); // ["apple", "orange"]
// Adding elements at a specific position
fruits.splice(1, 0, "banana", "kiwi"); // Insert at index 1, remove 0 elements
console.log(fruits); // ["apple", "banana", "kiwi", "orange"]
Array Methods
const numbers = [1, 2, 3, 4, 5];
// forEach - executes a function for each element
numbers.forEach(num => console.log(num * 2)); // Outputs: 2, 4, 6, 8, 10
// map - creates a new array by transforming each element
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// filter - creates a new array with elements that pass a test
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]
// reduce - reduces the array to a single value
const sum = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // 15
// find - returns the first element that passes a test
const found = numbers.find(num => num > 3);
console.log(found); // 4
// findIndex - returns the index of the first element that passes a test
const foundIndex = numbers.findIndex(num => num > 3);
console.log(foundIndex); // 3
// some - checks if at least one element passes a test
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // true
// every - checks if all elements pass a test
const allPositive = numbers.every(num => num > 0);
console.log(allPositive); // true
// includes - checks if an array contains a specific element
console.log(numbers.includes(3)); // true
console.log(numbers.includes(6)); // false
// join - joins all elements into a string
console.log(numbers.join(", ")); // "1, 2, 3, 4, 5"
// slice - returns a portion of an array
const sliced = numbers.slice(1, 4);
console.log(sliced); // [2, 3, 4]
Array Destructuring (ES6)
const rgb = [255, 128, 64];
// Basic destructuring
const [red, green, blue] = rgb;
console.log(red); // 255
console.log(green); // 128
console.log(blue); // 64
// Skipping elements
const [first, , third] = rgb;
console.log(first); // 255
console.log(third); // 64
// Rest pattern
const [head, ...tail] = [1, 2, 3, 4, 5];
console.log(head); // 1
console.log(tail); // [2, 3, 4, 5]
// Default values
const [a, b, c, d = 0] = [1, 2, 3];
console.log(d); // 0 (default value)
// Swapping variables
let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x); // 2
console.log(y); // 1
Spread Operator with Arrays
// Copying arrays
const original = [1, 2, 3];
const copy = [...original];
console.log(copy); // [1, 2, 3]
// Merging arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const merged = [...arr1, ...arr2];
console.log(merged); // [1, 2, 3, 4, 5, 6]
// Creating a new array with additional elements
const expanded = [...arr1, 7, 8, 9];
console.log(expanded); // [1, 2, 3, 7, 8, 9]
// Using spread with functions
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6
Working with JSON
JSON (JavaScript Object Notation) is a lightweight data interchange format that is easy for humans to read and write and easy for machines to parse and generate.
// Converting JavaScript objects to JSON strings
const person = {
name: "John",
age: 30,
isEmployed: true,
skills: ["JavaScript", "HTML", "CSS"]
};
const jsonString = JSON.stringify(person);
console.log(jsonString);
// {"name":"John","age":30,"isEmployed":true,"skills":["JavaScript","HTML","CSS"]}
// Pretty-printing JSON
const prettyJson = JSON.stringify(person, null, 2);
console.log(prettyJson);
// {
// "name": "John",
// "age": 30,
// "isEmployed": true,
// "skills": [
// "JavaScript",
// "HTML",
// "CSS"
// ]
// }
// Converting JSON strings back to JavaScript objects
const jsonData = '{"name":"Jane","age":25,"isEmployed":false}';
const parsedData = JSON.parse(jsonData);
console.log(parsedData.name); // "Jane"
console.log(parsedData.age); // 25
Interactive Example: Object Explorer
Best Practices for Objects and Arrays
- Use Object Literals: Prefer object literals over the
new Object()
syntax. - Use Array Literals: Prefer array literals over the
new Array()
syntax. - Use Destructuring: Use object and array destructuring for cleaner code.
- Use Spread Operator: Use the spread operator for copying and merging objects and arrays.
- Immutability: Treat objects and arrays as immutable when possible, creating new copies instead of modifying existing ones.
- Use Array Methods: Prefer array methods like
map
,filter
, andreduce
over traditional loops for cleaner, more functional code. - Property Shorthand: Use property shorthand when the property name matches the variable name.
- Method Shorthand: Use method shorthand in object literals.
- Computed Property Names: Use computed property names when property names are dynamic.
Next Steps
Now that you understand JavaScript objects and arrays, you can explore:
- Prototypes and inheritance
- Classes in JavaScript (ES6+)
- Advanced array manipulation techniques
- Working with complex data structures
- Map and Set objects