Most daily work with objects is about properties: reading, writing, deleting, and checking them. JavaScript gives you flexible ways to do all of these.
Dot vs Bracket Notation
Use dot notation for simple identifiers and bracket notation for dynamic or special keys.
const user = { 'first name': 'Ada', age: 36 };const prop = 'age';
// Dot notation: only for valid identifiersconsole.log(user.age); // 36
// Bracket notation: works with dynamic names and special charactersconsole.log(user[prop]); // 36 (using a variable)console.log(user['first name']); // "Ada" (space in key)Bracket notation is also handy when building objects in loops or from configuration.
// Build an object from an array of key-value pairsconst entries = [ ['id', 1], ['name', 'Ada'], ['role', 'admin'],];
const obj = {};
for (const [key, value] of entries) { obj[key] = value; // dynamic key using bracket notation}
console.log(obj); // { id: 1, name: 'Ada', role: 'admin' }Adding and Updating Properties
Just assign to a property. If it doesn’t exist, it’s created; if it exists, it’s updated.
const userProfile = {};
// Add new propertiesuserProfile.name = 'Ada';userProfile['age'] = 36;
console.log(userProfile); // { name: 'Ada', age: 36 }
// Update existing propertyuserProfile.age = 37;
console.log(userProfile.age); // 37You can also add methods after the object is created.
const car = { brand: 'Tesla', model: 'Model 3',};
// Add a method dynamicallycar.start = function () { console.log(`Starting ${this.brand} ${this.model}`);};
car.start(); // "Starting Tesla Model 3"Deleting Properties with delete
Use the delete operator to remove a property from an object.
const settings = { darkMode: true, showSidebar: true,};
delete settings.showSidebar;
console.log(settings); // { darkMode: true }console.log('showSidebar' in settings); // falsedelete only affects the object’s own properties; it won’t remove properties from the prototype.
Checking If a Property Exists
in Operator
The in operator checks if a property exists anywhere on the object, including its prototype chain.
const proto = { inherited: 1 };const obj = Object.create(proto);obj.own = 2;
console.log('own' in obj); // true (own property)console.log('inherited' in obj); // true (from prototype)console.log('missing' in obj); // falsehasOwnProperty and Object.hasOwn
These check only own properties (not inherited).
const base = { inherited: 1 };const child = Object.create(base);child.own = 2;
console.log(child.hasOwnProperty('own')); // trueconsole.log(child.hasOwnProperty('inherited')); // false
console.log(Object.hasOwn(child, 'own')); // true (modern, safer)console.log(Object.hasOwn(child, 'inherited')); // falsein vs Comparing to undefined
You can’t rely on obj.prop !== undefined to tell if a property exists, because the property might be explicitly set to undefined.
const config = { featureEnabled: undefined };
console.log('featureEnabled' in config); // trueconsole.log(config.featureEnabled !== undefined); // falseIf you care about existence vs value, prefer in or Object.hasOwn.
A Small Practical Example
Here’s a small function that safely reads a nested property with a default if it’s missing.
// Safe getter for nested properties using bracket notation and 'in'function getNested(obj, path, defaultValue) { const parts = path.split('.'); let current = obj;
for (const part of parts) { if (current && part in current) { current = current[part]; } else { return defaultValue; } }
return current;}
const settingsObj = { user: { theme: { name: 'dark', }, },};
console.log(getNested(settingsObj, 'user.theme.name', 'light')); // "dark"console.log(getNested(settingsObj, 'user.layout.type', 'single')); // "single"