By the end of this lesson, you will be able to inspect, create, and remove JavaScript object properties using enumeration methods, property descriptors, and deletion.
What it is
Managing properties means controlling the keys and values stored on an object. JavaScript objects have own properties and inherited properties. Enumeration asks which keys are visible. Defining creates or changes a property with metadata. Deleting removes an own property.
Mental model: a property is not just a key/value pair. It also has descriptor flags: value, writable, enumerable, and configurable. Accessor properties use get and set instead of value and writable.
Related terms: Object.keys, Object.getOwnPropertyNames, Reflect.ownKeys, for...in, Object.defineProperty, delete, Reflect.deleteProperty.
Why it matters
- Serialize only intended fields by making internal fields non-enumerable.
- Create computed properties with getters and setters.
- Protect data by making properties read-only or non-configurable.
- Debug objects by listing own keys instead of inherited keys.
- Remove stale keys so they do not appear in loops or JSON output.
Syntax or steps
Enumerate own enumerable string keys:
const user = { name: "Ada", age: 36 };
Object.keys(user); // ["name", "age"]
Enumerate all own string keys, including non-enumerable ones:
Object.getOwnPropertyNames(user);
Define a property with a descriptor:
Object.defineProperty(user, "id", {
value: 42,
writable: false,
enumerable: false,
configurable: false
});
Delete an own configurable property:
delete user.age;
Use for...in only when you want enumerable properties from the prototype chain, and guard with hasOwnProperty.
Example
const product = {
name: "Keyboard",
price: 89
};
Object.defineProperty(product, "discount", {
value: 10,
enumerable: false,
writable: true,
configurable: true
});
Object.defineProperty(product, "finalPrice", {
get() {
return this.price - this.discount;
},
enumerable: true,
configurable: true
});
console.log(Object.keys(product)); // ["name", "price", "finalPrice"]
console.log(product.finalPrice); // 79
delete product.price;
console.log("price" in product); // false
console.log(product.finalPrice); // NaN
Part-by-part explanation
The object starts with two normal properties: name and price. The discount property is defined as non-enumerable, so it does not appear in Object.keys. The finalPrice property is a getter, so it computes its value from price and discount. After deleting price, the getter still exists, but this.price is now undefined, so the subtraction produces NaN.
Common mistakes
- Using
for...inand assuming it lists only own properties. Fix: useObject.keysor checkObject.prototype.hasOwnProperty.call(obj, key). - Forgetting that
Object.definePropertydefaults new properties to non-enumerable, non-writable, and non-configurable. Fix: set descriptor flags explicitly. - Trying to delete a non-configurable property. Fix: make it configurable when defining it, or recreate the object without that key.
- Setting a property to
undefinedinstead of deleting it. Fix: usedelete obj.keywhen the key should disappear from enumeration andinchecks.
When to use it
Compare normal assignment with Object.defineProperty, and deletion with clearing a value.
| Task | Use | Why |
|---|---|---|
| Add a simple visible property | obj.x = 1 |
Short and enumerable by default. |
| Control visibility or mutability | Object.defineProperty |
Descriptors let you set enumerable, writable, configurable. |
| Remove a key completely | delete obj.x |
The key no longer appears in Object.keys or in. |
| Keep key but clear value | obj.x = undefined |
Useful when object shape should remain stable. |
Practice
Guided exercise: create an object called car with make and model. Define a non-enumerable vin property. List the keys and confirm vin is hidden.
const car = { make: "Toyota", model: "Corolla" };
Object.defineProperty(car, "vin", { value: "123", enumerable: false });
Object.keys(car); // ["make", "model"]
Challenge: add a getter called fullName to a person object with first and last, then delete last and observe the result.
Solution hint: define fullName with get() { return this.first + " " + this.last; }. After deleting last, the getter returns "Ada undefined".
Quick check
Question: Which method returns only an object's own enumerable string keys?
Answer: Object.keys(obj).
Summary
JavaScript properties have behavior, not just values. Use enumeration methods to inspect keys, Object.defineProperty to control descriptors, and delete to remove configurable own properties.