javascript

examples

examples.js
/**
 * ============================================
 * 7.1 OBJECT BASICS - EXAMPLES
 * ============================================
 */

/**
 * EXAMPLE 1: Object Literal Syntax
 * --------------------------------
 * The most common way to create objects
 */

console.log('=== Example 1: Object Literal ===');

const person = {
  name: 'Alice',
  age: 30,
  isEmployed: true,
  hobbies: ['reading', 'gaming'],
  address: {
    city: 'Boston',
    zip: '02101',
  },
};

console.log('Person:', person);
console.log('Name:', person.name);
console.log('City:', person.address.city);

/**
 * EXAMPLE 2: Different Ways to Create Objects
 * -------------------------------------------
 * Several ways to create objects
 */

console.log('\n=== Example 2: Creating Objects ===');

// Object literal (recommended)
const obj1 = { a: 1 };

// Object constructor (not recommended)
const obj2 = new Object();
obj2.a = 1;

// Object.create() - with null prototype
const obj3 = Object.create(null);
obj3.a = 1;

// Object.create() - with Object prototype
const obj4 = Object.create(Object.prototype);
obj4.a = 1;

console.log('Literal:', obj1);
console.log('Constructor:', obj2);
console.log('Create null:', obj3, 'hasOwnProperty:', obj3.hasOwnProperty);
console.log(
  'Create proto:',
  obj4,
  'hasOwnProperty:',
  typeof obj4.hasOwnProperty
);

/**
 * EXAMPLE 3: Property Access
 * --------------------------
 * Dot notation vs bracket notation
 */

console.log('\n=== Example 3: Property Access ===');

const user = {
  name: 'Bob',
  'full-name': 'Bob Smith',
  '1stPlace': true,
  email: 'bob@example.com',
};

// Dot notation (clean, common)
console.log('Dot - name:', user.name);
console.log('Dot - email:', user.email);

// Bracket notation (flexible)
console.log('Bracket - name:', user['name']);
console.log('Bracket - full-name:', user['full-name']);
console.log('Bracket - 1stPlace:', user['1stPlace']);

// With variables
const property = 'email';
console.log('Variable - email:', user[property]);

/**
 * EXAMPLE 4: Dynamic Property Names
 * ---------------------------------
 * Using variables and expressions as keys
 */

console.log('\n=== Example 4: Dynamic Properties ===');

const dynamicKey = 'dynamicProperty';

const dynamicObj = {
  staticProperty: "I'm static",
  [dynamicKey]: "I'm dynamic",
  ['computed' + 'Key']: "I'm computed",
  [1 + 2]: 'At index 3',
};

console.log('Static:', dynamicObj.staticProperty);
console.log('Dynamic:', dynamicObj.dynamicProperty);
console.log('Computed:', dynamicObj.computedKey);
console.log('Index 3:', dynamicObj[3]);

/**
 * EXAMPLE 5: Shorthand Properties
 * -------------------------------
 * ES6 property shorthand
 */

console.log('\n=== Example 5: Shorthand Properties ===');

const firstName = 'Alice';
const lastName = 'Smith';
const age = 30;

// Old way
const person1 = {
  firstName: firstName,
  lastName: lastName,
  age: age,
};

// ES6 shorthand
const person2 = { firstName, lastName, age };

console.log('Old way:', person1);
console.log('Shorthand:', person2);

/**
 * EXAMPLE 6: Shorthand Methods
 * ----------------------------
 * ES6 method shorthand
 */

console.log('\n=== Example 6: Shorthand Methods ===');

// Old way
const calc1 = {
  add: function (a, b) {
    return a + b;
  },
};

// ES6 shorthand
const calc2 = {
  add(a, b) {
    return a + b;
  },
  subtract(a, b) {
    return a - b;
  },
};

console.log('Old way add:', calc1.add(5, 3));
console.log('Shorthand add:', calc2.add(5, 3));
console.log('Shorthand subtract:', calc2.subtract(5, 3));

/**
 * EXAMPLE 7: Adding and Modifying Properties
 * ------------------------------------------
 * Objects are mutable
 */

console.log('\n=== Example 7: Adding/Modifying Properties ===');

const car = { brand: 'Toyota' };
console.log('Initial:', car);

// Add properties
car.model = 'Camry';
car['year'] = 2023;
console.log('After adding:', car);

// Modify properties
car.year = 2024;
console.log('After modifying:', car);

/**
 * EXAMPLE 8: Deleting Properties
 * ------------------------------
 * Remove properties with delete
 */

console.log('\n=== Example 8: Deleting Properties ===');

const item = {
  id: 1,
  name: 'Widget',
  temp: 'will be deleted',
};
console.log('Before delete:', item);

delete item.temp;
console.log('After delete:', item);
console.log('item.temp:', item.temp); // undefined

/**
 * EXAMPLE 9: Checking for Properties
 * ----------------------------------
 * Different ways to check if property exists
 */

console.log('\n=== Example 9: Checking Properties ===');

const obj = {
  name: 'Test',
  value: undefined,
  zero: 0,
  empty: '',
};

// Using 'in' operator
console.log("'name' in obj:", 'name' in obj); // true
console.log("'value' in obj:", 'value' in obj); // true
console.log("'missing' in obj:", 'missing' in obj); // false
console.log("'toString' in obj:", 'toString' in obj); // true (inherited)

// Using hasOwnProperty
console.log("\nhasOwnProperty('name'):", obj.hasOwnProperty('name')); // true
console.log("hasOwnProperty('toString'):", obj.hasOwnProperty('toString')); // false

// Checking for undefined (risky!)
console.log('\nobj.value === undefined:', obj.value === undefined); // true
console.log('obj.missing === undefined:', obj.missing === undefined); // true (but doesn't exist!)

/**
 * EXAMPLE 10: Nested Objects
 * --------------------------
 * Objects within objects
 */

console.log('\n=== Example 10: Nested Objects ===');

const company = {
  name: 'TechCorp',
  address: {
    street: '123 Tech Ave',
    city: 'San Francisco',
    country: 'USA',
  },
  employees: {
    count: 100,
    departments: ['Engineering', 'Sales', 'HR'],
  },
};

console.log('Company:', company.name);
console.log('City:', company.address.city);
console.log('Departments:', company.employees.departments);

// Modifying nested properties
company.address.zip = '94102';
console.log('Added zip:', company.address);

/**
 * EXAMPLE 11: Optional Chaining
 * -----------------------------
 * Safe access to nested properties
 */

console.log('\n=== Example 11: Optional Chaining ===');

const data = {
  user: {
    profile: {
      name: 'Alice',
    },
  },
};

// Safe access
console.log('Name:', data.user?.profile?.name); // "Alice"
console.log('Missing:', data.user?.settings?.theme); // undefined
console.log('Deep missing:', data.other?.nested?.value); // undefined

// Without optional chaining, these would throw errors:
// data.other.nested.value // TypeError!

/**
 * EXAMPLE 12: Nullish Coalescing
 * ------------------------------
 * Default values for null/undefined
 */

console.log('\n=== Example 12: Nullish Coalescing ===');

const config = {
  timeout: 0, // Falsy but valid
  retries: null, // Needs default
  name: '', // Falsy but valid
};

// || treats 0 and "" as falsy (often wrong)
console.log('timeout ||:', config.timeout || 5000); // 5000 (wrong!)
console.log('name ||:', config.name || 'default'); // "default" (wrong!)

// ?? only treats null/undefined as missing
console.log('timeout ??:', config.timeout ?? 5000); // 0 (correct!)
console.log('name ??:', config.name ?? 'default'); // "" (correct!)
console.log('retries ??:', config.retries ?? 3); // 3 (correct!)

/**
 * EXAMPLE 13: Property Order
 * --------------------------
 * Properties have a defined order
 */

console.log('\n=== Example 13: Property Order ===');

const mixed = {
  c: 3,
  2: 'two',
  b: 2,
  1: 'one',
  a: 1,
  10: 'ten',
};

console.log('Keys:', Object.keys(mixed));
// Integer keys first (sorted), then string keys (insertion order)
// ["1", "2", "10", "c", "b", "a"]

/**
 * EXAMPLE 14: Symbols as Keys
 * ---------------------------
 * Unique, non-string keys
 */

console.log('\n=== Example 14: Symbol Keys ===');

const id = Symbol('id');
const secret = Symbol('secret');

const account = {
  name: 'Savings',
  [id]: 12345,
  [secret]: 'hidden',
};

console.log('Name:', account.name);
console.log('ID:', account[id]);
console.log('Keys:', Object.keys(account)); // ["name"]
console.log('Own props:', Object.getOwnPropertySymbols(account)); // [Symbol(id), Symbol(secret)]

/**
 * EXAMPLE 15: Object from Arrays
 * ------------------------------
 * Creating objects from key-value pairs
 */

console.log('\n=== Example 15: Object from Arrays ===');

// From entries (array of [key, value] pairs)
const entries = [
  ['name', 'Alice'],
  ['age', 30],
  ['city', 'Boston'],
];
const fromEntries = Object.fromEntries(entries);
console.log('From entries:', fromEntries);

// From two parallel arrays
const keys = ['a', 'b', 'c'];
const values = [1, 2, 3];
const combined = Object.fromEntries(keys.map((key, i) => [key, values[i]]));
console.log('Combined:', combined);

/**
 * EXAMPLE 16: Computed Property Names in Practice
 * ------------------------------------------------
 * Real-world use cases
 */

console.log('\n=== Example 16: Computed Properties in Practice ===');

// Form data handling
const formField = 'username';
const formValue = 'alice123';
const formData = {
  [formField]: formValue,
  [`${formField}_validated`]: true,
};
console.log('Form data:', formData);

// Dynamic configuration
const env = 'production';
const settings = {
  [`${env}_api_url`]: 'https://api.example.com',
  [`${env}_debug`]: false,
};
console.log('Settings:', settings);

// Counter/tracker object
function createCounter(name) {
  return {
    [`${name}Count`]: 0,
    [`increment${name}`]() {
      this[`${name}Count`]++;
    },
  };
}
const clickCounter = createCounter('click');
console.log('Counter:', clickCounter);

console.log('\n=== End of Examples ===');
Examples - JavaScript Tutorial | DeepML