JavaScript Object Data Type
Object Basics
Objects are complex data types in JavaScript that store collections of key-value pairs. They are used to represent real-world entities and organize related data and functionality.
1// Object declaration examples
2let person = {
3 name: "Alice",
4 age: 30
5};
6
7const car = {
8 brand: "Toyota",
9 model: "Camry",
10 year: 2022
11};
12
13let book = {
14 title: "JavaScript Guide",
15 author: "John Doe",
16 pages: 350
17};
18
19console.log(person); // Output: { name: "Alice", age: 30 }
20console.log(car); // Output: { brand: "Toyota", model: "Camry", year: 2022 }
21console.log(book); // Output: { title: "JavaScript Guide", author: "John Doe", pages: 350 }
22
23// Accessing object properties
24console.log(person.name); // Output: "Alice"
25console.log(car["model"]); // Output: "Camry"
26console.log(book.title); // Output: "JavaScript Guide"Object Characteristics
Key-Value Pairs- Store data as properties with keys and valuesReference Type- Stored by reference, not by valueMutable- Properties can be added, modified, or deletedDynamic- Properties can be created and changed at runtime
Object Declaration Methods
Objects can be created using various methods including object literals, constructors, and modern JavaScript features.
1// Method 1: Object literal (most common)
2let person = {
3 firstName: "John",
4 lastName: "Doe",
5 age: 30,
6 isEmployed: true
7};
8
9// Method 2: Object constructor
10let car = new Object();
11car.brand = "Honda";
12car.model = "Civic";
13car.year = 2023;
14
15// Method 3: Object.create()
16let prototypeObj = { type: "animal" };
17let dog = Object.create(prototypeObj);
18dog.name = "Buddy";
19dog.breed = "Golden Retriever";
20
21// Method 4: Using class (ES6)
22class Person {
23 constructor(name, age) {
24 this.name = name;
25 this.age = age;
26 }
27}
28let user = new Person("Alice", 25);
29
30// Method 5: Dynamic property names
31let dynamicKey = "score";
32let game = {
33 player: "Bob",
34 [dynamicKey]: 95,
35 ["level" + "Number"]: 5
36};
37
38console.log(person); // Output: { firstName: "John", lastName: "Doe", age: 30, isEmployed: true }
39console.log(car); // Output: { brand: "Honda", model: "Civic", year: 2023 }
40console.log(dog); // Output: { name: "Buddy", breed: "Golden Retriever" }
41console.log(user); // Output: Person { name: "Alice", age: 25 }
42console.log(game); // Output: { player: "Bob", score: 95, levelNumber: 5 }Object Creation Methods
Object Literal- {} syntax - most common and readableConstructor- new Object() - less common, same as literalObject.create()- Creates object with specific prototypeClass Syntax- ES6 classes for object-oriented patterns
Object Properties and Methods
Objects contain properties (data) and methods (functions). Properties can be accessed using dot notation or bracket notation.
1// Object with properties and methods
2let person = {
3 // Properties (data)
4 firstName: "Alice",
5 lastName: "Smith",
6 age: 30,
7 email: "alice@example.com",
8
9 // Methods (functions)
10 getFullName: function() {
11 return this.firstName + " " + this.lastName;
12 },
13
14 // Shorthand method syntax (ES6)
15 celebrateBirthday() {
16 this.age++;
17 return `Happy birthday! You are now ${this.age} years old.`;
18 },
19
20 // Arrow function (be careful with 'this')
21 getEmail: () => {
22 return person.email; // Use object name instead of 'this'
23 }
24};
25
26// Accessing properties
27console.log(person.firstName); // Dot notation
28console.log(person["lastName"]); // Bracket notation
29
30// Calling methods
31console.log(person.getFullName()); // Output: "Alice Smith"
32console.log(person.celebrateBirthday()); // Output: "Happy birthday! You are now 31 years old."
33console.log(person.getEmail()); // Output: "alice@example.com"
34
35// Dynamic property access
36let propertyName = "age";
37console.log(person[propertyName]); // Output: 31
38
39// Nested objects
40let company = {
41 name: "Tech Corp",
42 address: {
43 street: "123 Main St",
44 city: "Boston",
45 zipCode: "02101"
46 },
47 employees: ["Alice", "Bob", "Charlie"]
48};
49
50console.log(company.address.city); // Output: "Boston"
51console.log(company.employees[0]); // Output: "Alice"Property Access Methods
Dot Notation- obj.property - clean syntax for known propertiesBracket Notation- obj["property"] - for dynamic or special character propertiesMethod Definition- Functions inside objects that operate on object dataNested Access- Access properties within nested objects
Object Manipulation
Objects are mutable - you can add, modify, and delete properties after creation. Understanding mutation is key to working with objects effectively.
1// Creating an object
2let person = {
3 name: "John",
4 age: 25
5};
6
7// Adding new properties
8person.email = "john@example.com";
9person["phone"] = "555-1234";
10person.address = {
11 street: "456 Oak St",
12 city: "New York"
13};
14
15// Modifying existing properties
16person.age = 26;
17person["name"] = "John Doe";
18
19// Deleting properties
20delete person.phone;
21
22console.log(person);
23// Output: { name: "John Doe", age: 26, email: "john@example.com", address: { ... } }
24
25// Checking property existence
26console.log("name" in person); // Output: true
27console.log(person.hasOwnProperty("email")); // Output: true
28console.log(person.phone === undefined); // Output: true (deleted)
29
30// Getting all properties
31console.log(Object.keys(person)); // Output: ["name", "age", "email", "address"]
32console.log(Object.values(person)); // Output: ["John Doe", 26, "john@example.com", { ... }]
33console.log(Object.entries(person)); // Output: [["name", "John Doe"], ["age", 26], ...]
34
35// Object iteration
36for (let key in person) {
37 if (person.hasOwnProperty(key)) {
38 console.log(`${key}: ${person[key]}`);
39 }
40}
41
42// Copying objects (shallow copy)
43let personCopy = Object.assign({}, person);
44let spreadCopy = { ...person };
45
46// Merging objects
47let defaults = { theme: "light", language: "en" };
48let userSettings = { theme: "dark" };
49let merged = Object.assign({}, defaults, userSettings);
50console.log(merged); // Output: { theme: "dark", language: "en" }Built-in Object Methods
JavaScript provides built-in methods for working with objects, including property management, copying, freezing, and sealing.
1let person = {
2 name: "Alice",
3 age: 30,
4 occupation: "Developer"
5};
6
7// Object.keys() - get all property names
8console.log(Object.keys(person)); // Output: ["name", "age", "occupation"]
9
10// Object.values() - get all property values
11console.log(Object.values(person)); // Output: ["Alice", 30, "Developer"]
12
13// Object.entries() - get key-value pairs
14console.log(Object.entries(person));
15// Output: [["name", "Alice"], ["age", 30], ["occupation", "Developer"]]
16
17// Object.assign() - copy or merge objects
18let copy = Object.assign({}, person);
19let extended = Object.assign({}, person, { city: "Boston" });
20console.log(extended); // Output: { name: "Alice", age: 30, occupation: "Developer", city: "Boston" }
21
22// Object.freeze() - make object immutable
23let frozen = Object.freeze({ data: "cannot change" });
24// frozen.data = "new value"; // Error in strict mode
25console.log(Object.isFrozen(frozen)); // Output: true
26
27// Object.seal() - prevent adding/removing properties
28let sealed = Object.seal({ value: 42 });
29sealed.value = 100; // Allowed
30// sealed.newProp = "test"; // Error
31console.log(Object.isSealed(sealed)); // Output: true
32
33// Object.hasOwn() - check property existence (modern)
34console.log(Object.hasOwn(person, "name")); // Output: true
35console.log(Object.hasOwn(person, "toString")); // Output: false (inherited)
36
37// Object.defineProperty() - define property with attributes
38let obj = {};
39Object.defineProperty(obj, 'readOnly', {
40 value: 42,
41 writable: false,
42 enumerable: true
43});
44// obj.readOnly = 100; // Error in strict mode
45console.log(obj.readOnly); // Output: 42
46
47// Object.getPrototypeOf() - get object's prototype
48console.log(Object.getPrototypeOf(person)); // Output: {}
49
50// Object.create() - create with specific prototype
51let proto = { greet() { return "Hello!"; } };
52let newObj = Object.create(proto);
53newObj.name = "Bob";
54console.log(newObj.greet()); // Output: "Hello!"Common Object Patterns
Objects are used in various patterns including configuration objects, factory functions, namespaces, and modules.
1// Pattern 1: Configuration objects
2const appConfig = {
3 apiUrl: "https://api.example.com",
4 timeout: 5000,
5 retryAttempts: 3,
6 features: {
7 auth: true,
8 caching: false,
9 analytics: true
10 }
11};
12
13// Pattern 2: Factory function
14function createUser(name, email, age) {
15 return {
16 name,
17 email,
18 age,
19 isActive: true,
20 lastLogin: new Date(),
21 getProfile() {
22 return `${this.name} (${this.email})`;
23 }
24 };
25}
26
27let user1 = createUser("Alice", "alice@example.com", 30);
28let user2 = createUser("Bob", "bob@example.com", 25);
29
30// Pattern 3: Namespace pattern
31const MyApp = {
32 utils: {
33 formatDate(date) { /* ... */ },
34 validateEmail(email) { /* ... */ }
35 },
36 config: {
37 version: "1.0.0",
38 environment: "production"
39 },
40 init() {
41 console.log("App initialized");
42 }
43};
44
45// Pattern 4: Computed property names
46function createDynamicObject(prefix, values) {
47 let result = {};
48 values.forEach((value, index) => {
49 result[`${prefix}_${index}`] = value;
50 });
51 return result;
52}
53
54let dynamicObj = createDynamicObject("item", ["a", "b", "c"]);
55console.log(dynamicObj); // Output: { item_0: "a", item_1: "b", item_2: "c" }
56
57// Pattern 5: Object destructuring
58const { name, age, email } = user1;
59console.log(name, age, email); // Output: "Alice" 30 "alice@example.com"
60
61// Pattern 6: Object as function parameter with defaults
62function processOptions({
63 timeout = 5000,
64 retries = 3,
65 debug = false
66} = {}) {
67 console.log(`Timeout: ${timeout}, Retries: ${retries}, Debug: ${debug}`);
68}
69
70processOptions({ timeout: 10000, debug: true });
71
72// Pattern 7: Private properties convention
73function createCounter() {
74 let _count = 0; // "private" variable
75
76 return {
77 increment() {
78 _count++;
79 },
80 getCount() {
81 return _count;
82 }
83 };
84}
85
86let counter = createCounter();
87counter.increment();
88console.log(counter.getCount()); // Output: 1Object Best Practices
Following best practices when working with objects leads to more maintainable, predictable, and efficient code.
1// Use const for objects that won't be reassigned
2const config = {
3 apiKey: "abc123",
4 maxRetries: 3
5};
6
7// config = {}; // Error - cannot reassign const
8config.apiKey = "def456"; // OK - modifying properties is allowed
9
10// Use descriptive property names
11const goodExample = {
12 firstName: "John", // GOOD
13 userAge: 25, // GOOD
14 isEmailVerified: true // GOOD
15};
16
17const badExample = {
18 fn: "John", // BAD - unclear
19 a: 25, // BAD - meaningless
20 ev: true // BAD - ambiguous
21};
22
23// Use object shorthand when possible
24const name = "Alice";
25const age = 30;
26
27const person = { name, age }; // GOOD - shorthand
28// const person = { name: name, age: age }; // REDUNDANT
29
30// Use method shorthand syntax
31const calculator = {
32 add(a, b) { // GOOD - method shorthand
33 return a + b;
34 },
35 multiply(a, b) {
36 return a * b;
37 }
38};
39
40// Avoid arrow functions for methods (due to 'this' binding)
41const obj = {
42 value: 42,
43 badMethod: () => {
44 // console.log(this.value); // undefined - 'this' doesn't refer to obj
45 },
46 goodMethod() {
47 console.log(this.value); // 42 - 'this' refers to obj
48 }
49};
50
51// Use Object.freeze() for constants
52const CONSTANTS = Object.freeze({
53 PI: 3.14159,
54 MAX_USERS: 1000,
55 SUPPORTED_LANGUAGES: ["en", "es", "fr"]
56});
57
58// Use destructuring for clean property extraction
59const user = { name: "Bob", age: 35, email: "bob@example.com" };
60const { name: userName, email } = user; // GOOD
61console.log(userName, email); // Output: "Bob" "bob@example.com"
62
63// Use spread operator for object copying
64const original = { a: 1, b: 2 };
65const copy = { ...original, c: 3 }; // GOOD
66// const copy = Object.assign({}, original, { c: 3 }); // OK but more verbose
67
68// Check property existence safely
69const data = { value: 42 };
70
71if ("value" in data) { // GOOD - checks own and inherited
72 console.log(data.value);
73}
74
75if (data.hasOwnProperty("value")) { // GOOD - checks own properties only
76 console.log(data.value);
77}
78
79if (data.value !== undefined) { // OK but doesn't distinguish missing vs undefined
80 console.log(data.value);
81}