Object Methods Get Certified
JavaScript provides a rich set of built-in methods on the
Object constructor that make working with objects
much more convenient. These methods help you inspect, copy,
merge, lock, and create objects safely.
In this lesson you will learn the most useful Object methods, when to use each one, and the common mistakes to avoid.
Object.keys(), Object.values(), Object.entries()
These three methods turn an object’s contents into arrays so you can easily loop over them or transform them.
What this code does: Object.keys returns an array of the object’s own property names.
Object.values returns the values, and Object.entries returns key-value pairs.
const product = {
name: "Wireless Mouse",
price: 25,
inStock: true
};
console.log(Object.keys(product));
console.log(Object.values(product));
console.log(Object.entries(product));
const product = { begins a plain object that will hold product data.name: "Wireless Mouse", stores the product name as a string.price: 25, stores the numeric price.inStock: true stores a boolean indicating availability.}; finishes the object literal.console.log(Object.keys(product)); returns an array of the object’s own property names: ["name", "price", "inStock"].console.log(Object.values(product)); returns an array of the corresponding values: ["Wireless Mouse", 25, true].console.log(Object.entries(product)); returns an array of [key, value] pairs so you can work with both at once.
What this code does: Looping over Object.entries is a clean way to process every property.
Each iteration gives you both the key and the value.
const scores = { Alice: 92, Ben: 87, Chloe: 95 };
for (const [name, score] of Object.entries(scores)) {
console.log(name + " scored " + score);
}
const scores = { Alice: 92, Ben: 87, Chloe: 95 }; stores student names as keys and their scores as values.for (const [name, score] of Object.entries(scores)) { turns the object into an array of pairs and destructures each pair into the variables name and score.console.log(name + " scored " + score); builds and prints a clear sentence for each student.} closes the for...of loop.Object.fromEntries()
Object.fromEntries() does the opposite of
Object.entries(): it builds an object from an array
of key-value pairs.
What this code does: Object.fromEntries turns an array of pairs back into an object.
This is useful after transforming entries with map or filter.
const pairs = [
["brand", "Nike"],
["size", 10],
["color", "black"]
];
const shoe = Object.fromEntries(pairs);
console.log(shoe);
const pairs = [ begins an array that will hold key-value pairs.["brand", "Nike"], is the first [key, value] pair.["size", 10], is the second pair.["color", "black"] is the third pair.];const shoe = Object.fromEntries(pairs); converts the array of pairs into a plain object.console.log(shoe); prints { brand: "Nike", size: 10, color: "black" }.What this code does: A common pattern: convert to entries, transform the values, then rebuild the object. Every price is increased by 10%.
const prices = { apple: 1.2, banana: 0.8, orange: 1.5 };
const inflated = Object.fromEntries(
Object.entries(prices).map(([fruit, price]) => [fruit, price * 1.1])
);
console.log(inflated);
const prices = { apple: 1.2, banana: 0.8, orange: 1.5 };const inflated = Object.fromEntries( will rebuild an object from transformed pairs.Object.entries(prices).map(([fruit, price]) => [fruit, price * 1.1]) multiplies every price by 1.1 while keeping the same keys.);console.log(inflated); prints the new object with each price increased by 10 %.Object.assign()
Object.assign() copies properties from one or more
source objects into a target object. It is commonly used to merge
objects or create shallow copies.
What this code does: Object.assign copies properties into the first argument (the target).
Passing an empty object as the target creates a new merged object without mutating the sources.
const defaults = { theme: "light", fontSize: 14 };
const userSettings = { theme: "dark" };
const settings = Object.assign({}, defaults, userSettings);
console.log(settings);
console.log(defaults); // unchanged
const defaults = { theme: "light", fontSize: 14 };const userSettings = { theme: "dark" };const settings = Object.assign({}, defaults, userSettings); copies properties from both sources into a fresh empty object. Later sources overwrite earlier ones for the same key.console.log(settings); prints { theme: "dark", fontSize: 14 }.console.log(defaults); // unchanged confirms that the source object was not mutated.What this code does: Later sources override earlier ones. The final settings keep the dark theme and the default notifications value.
const defaults = { theme: "light", notifications: true };
const userPrefs = { theme: "dark" };
const finalSettings = Object.assign({}, defaults, userPrefs);
console.log(finalSettings);
const defaults = { theme: "light", notifications: true };const userPrefs = { theme: "dark" };const finalSettings = Object.assign({}, defaults, userPrefs); the empty object is the target, so neither source is mutated. userPrefs.theme overwrites defaults.theme.console.log(finalSettings); prints { theme: "dark", notifications: true }.Object.freeze()
Object.freeze() prevents any changes to an object:
properties cannot be added, removed, or modified afterward.
What this code does: Object.freeze() locks an object: you cannot add, remove, or change properties.
Attempts to update founded or add city are ignored (in non-strict mode).
const teamRoster = Object.freeze({
name: "Ravens FC",
founded: 1998
});
teamRoster.founded = 2000;
teamRoster.city = "Denver";
console.log(teamRoster);
const teamRoster = Object.freeze({ freezes the object at the same moment it is created.name: "Ravens FC",founded: 1998});teamRoster.founded = 2000; has no effect because the object is frozen (fails silently outside strict mode).teamRoster.city = "Denver"; is also ignored.console.log(teamRoster); still shows the original values.
Both attempted changes are silently ignored outside strict mode
(or throw a TypeError inside strict mode), and
teamRoster remains exactly as it was.
Object.isFrozen()
What this code does: Object.isFrozen() checks whether an object is frozen.
The roster returns true; a plain object returns false.
const teamRoster = Object.freeze({ name: "Ravens FC" });
const otherTeam = { name: "Falcons FC" };
console.log(Object.isFrozen(teamRoster));
console.log(Object.isFrozen(otherTeam));
const teamRoster = Object.freeze({ name: "Ravens FC" });const otherTeam = { name: "Falcons FC" };console.log(Object.isFrozen(teamRoster)); returns true.console.log(Object.isFrozen(otherTeam)); returns false.
Note that Object.freeze() is shallow — it only
protects the object’s own properties, not the contents of any
nested objects inside it.
Object.seal()
Object.seal() is a bit less strict than
freeze(): it prevents adding or removing properties,
but still allows existing properties to be modified.
What this code does: Object.seal() prevents adding or removing properties,
but existing ones can still be changed. Difficulty updates; subtitles cannot be added.
const gameSettings = Object.seal({
difficulty: "normal",
musicVolume: 80
});
gameSettings.difficulty = "hard";
gameSettings.subtitles = true;
console.log(gameSettings);
const gameSettings = Object.seal({difficulty: "normal",musicVolume: 80});gameSettings.difficulty = "hard"; succeeds because seal still allows modification of existing properties.gameSettings.subtitles = true; is ignored because new properties cannot be added to a sealed object.console.log(gameSettings); shows the updated difficulty but no subtitles property.
The difficulty value updates successfully, but the
new subtitles property is silently rejected, since
sealing prevents adding new properties.
Object.freeze() vs. Object.seal()
| Operation | Object.freeze() | Object.seal() |
|---|---|---|
| Add new properties | Blocked | Blocked |
| Remove properties | Blocked | Blocked |
| Modify existing properties | Blocked | Allowed |
Object.create()
Object.create() creates a brand-new object with a
specified prototype, allowing that object to inherit properties
and methods from another object.
What this code does: Object.create() makes an object that inherits from a given prototype.
The scooter gets describe from the prototype and uses its own make and model.
const vehiclePrototype = {
describe: function () {
return this.make + " " + this.model;
}
};
const scooter = Object.create(vehiclePrototype);
scooter.make = "Zipline";
scooter.model = "E200";
console.log(scooter.describe());
const vehiclePrototype = {describe: function () {return this.make + " " + this.model; uses this so the method works on any object that inherits it.}};const scooter = Object.create(vehiclePrototype);scooter.make = "Zipline";scooter.model = "E200";console.log(scooter.describe()); looks up describe on the prototype chain and prints Zipline E200.
The describe method isn’t copied onto
scooter directly — it’s inherited through the
prototype chain.
Object.getPrototypeOf()
Object.getPrototypeOf() returns the prototype of a
given object, which can be useful for inspecting where an
object’s inherited properties come from.
What this code does: Object.getPrototypeOf() returns the object’s prototype.
Confirming it matches vehiclePrototype shows the inheritance link.
const vehiclePrototype = {
wheels: 4
};
const scooter = Object.create(vehiclePrototype);
console.log(Object.getPrototypeOf(scooter) === vehiclePrototype);
const vehiclePrototype = {wheels: 4};const scooter = Object.create(vehiclePrototype);console.log(Object.getPrototypeOf(scooter) === vehiclePrototype); returns true, confirming the inheritance link.Comparing Objects
Objects are compared by reference, not by their contents.
Object.is() behaves almost identically to
===, but with slightly different handling for a few
special numeric values.
What this code does: Objects are compared by reference, not by contents. Two separate objects with the same data are not equal; assigning one variable to another shares the same reference.
const menuA = { item: "Latte", price: 4.75 };
const menuB = { item: "Latte", price: 4.75 };
const menuC = menuA;
console.log(menuA === menuB);
console.log(menuA === menuC);
console.log(Object.is(menuA, menuC));
const menuA = { item: "Latte", price: 4.75 };const menuB = { item: "Latte", price: 4.75 }; is a completely separate object in memory.const menuC = menuA; points to the exact same object as menuA.console.log(menuA === menuB); returns false because they are two distinct objects.console.log(menuA === menuC); returns true.console.log(Object.is(menuA, menuC)); also returns true.
Even though menuA and menuB have
identical contents, they are different objects in memory, so the
comparison is false. menuC, however,
points to the exact same object as menuA.
Practical Example
Let’s combine several Object methods to merge default
settings with user overrides, then lock the result so it can’t be
accidentally changed later.
What this code does: Merge defaults with user choices, then freeze the result. The final profile is locked so nothing can change it later.
const defaultProfile = {
displayName: "Guest",
language: "en",
theme: "light"
};
const userChoices = {
displayName: "Michael",
theme: "dark"
};
const finalProfile = Object.freeze(
Object.assign({}, defaultProfile, userChoices)
);
console.log(finalProfile);
console.log(Object.isFrozen(finalProfile));
const defaultProfile = {displayName: "Guest",language: "en",theme: "light"};const userChoices = {displayName: "Michael",theme: "dark"};const finalProfile = Object.freeze(Object.assign({}, defaultProfile, userChoices) first creates a new object that combines defaults and overrides.); then freezes that combined object so nothing can change it later.console.log(finalProfile);console.log(Object.isFrozen(finalProfile)); returns true.Common Mistakes With Object Methods
- Forgetting to pass an empty object as the first argument to
Object.assign(), accidentally overwriting one of the source objects. - Assuming
Object.freeze()also protects nested objects, when it only prevents changes at the top level. - Comparing two separate objects with identical contents using
===and expectingtrue. - Confusing
Object.seal()withObject.freeze(), and being surprised that sealed objects can still have their existing properties changed. - Forgetting that changes to a frozen object fail silently outside of strict mode, making the mistake easy to miss.
Best Practices for Object Methods
- Prefer the spread operator (
{ ...obj }) orObject.assign({}, ...)for merging objects without mutating the originals. - Use
Object.freeze()for configuration or constant objects that should never change after creation. - Reach for
Object.entries()combined withObject.fromEntries()when you need to transform an object’s values while keeping the same keys. - Remember that object equality checks compare references, not contents — write a dedicated comparison function if you need to compare values deeply.
- Use
Object.isFrozen()orObject.isSealed()when debugging unexpected “changes not taking effect” issues.
Quick Summary
Object.keys(),Object.values(), andObject.entries()extract an object’s keys, values, or both as arrays.Object.fromEntries()builds an object back up from an array of key-value pairs.Object.assign()merges properties from source objects into a target object.Object.freeze()locks an object completely;Object.seal()allows existing properties to still be modified.Object.create()builds an object with a specific prototype for inheritance.- Objects are compared by reference, not by their contents.
Try It Yourself
Modify the code below. Try adding another override property, or checking whether the final result is frozen.
What this code does: Practice example: merge a base recipe with customizations,
then inspect the result with Object.keys. Try adding more overrides or freezing the result.
const baseRecipe = { name: "Pancakes", servings: 4, spicy: false };
const customizations = { servings: 8 };
const finalRecipe = Object.assign({}, baseRecipe, customizations);
console.log(finalRecipe);
console.log(Object.keys(finalRecipe));
const baseRecipe = { name: "Pancakes", servings: 4, spicy: false };const customizations = { servings: 8 };const finalRecipe = Object.assign({}, baseRecipe, customizations); copies properties from both sources into a fresh object; the later source wins for colliding keys.console.log(finalRecipe);console.log(Object.keys(finalRecipe)); prints the property names of the result. Try adding more overrides or freezing the object.
Tip:
When merging configuration objects, put your defaults first and
overrides last in Object.assign() — later arguments
always win, which mirrors how most configuration systems are
expected to behave.
Understanding these built-in Object methods is
useful before moving on to classes, prototypes, and more advanced
JavaScript concepts.
🧪 Test Your JavaScript Code
Edit the code on the left and click “Run Code” to see the console output on the right.
Click “Run Code” to see the output here.
Code Explanation
The complete example stays visible. Use Previous and Next to move through its logical blocks.
Select Next to begin exploring the code.