What an Object Actually Is
Before classes, before inheritance, before any of the vocabulary: an object is a labelled bundle of things that belong together. That is the whole idea.
By the end: Make an object by hand and read values back out of it.
Say you are keeping records for a motor park full of buses. One of them carries the plate LAG-441-XA. It runs Lagos to Abuja, it has nine seats still unsold, and it was registered in 2019.
You could store that with four separate variables:
const plate = 'LAG-441-XA';
const route = 'Lagos - Abuja';
const seatsLeft = 9;
const registeredIn = 2019;
Nothing here says these four facts describe the same bus. Add a second bus and you are inventing names like plate2 and seatsLeft2. Add forty and the whole thing collapses.
An object solves exactly this and nothing more. It is one value that holds named facts which belong together.
const bus = {
plate: 'LAG-441-XA',
route: 'Lagos - Abuja',
seatsLeft: 9,
registeredIn: 2019,
};
console.log(bus);
Output
Read that syntax slowly, because you will type it thousands of times.
- The curly braces
{ }mean "an object starts here". - Inside, each line is a key, then a colon, then a value.
- Entries are separated by commas. The comma after the last one is optional and harmless; keep it, it makes adding lines cleaner.
The key is the label. The value is the thing. That pair together is called a property.
Getting things back out
Two ways in. Dot notation is what you will use almost always:
const bus = { plate: 'LAG-441-XA', seatsLeft: 9, registeredIn: 2019 };
console.log(bus.plate);
console.log(bus.seatsLeft);
// Brackets do the same job, but the key is written as a string.
console.log(bus['registeredIn']);
// Which means brackets can take a key you worked out at runtime.
const whichOne = 'seatsLeft';
console.log(bus[whichOne]);
Output
Ask for a property that is not there and JavaScript does not complain. It hands you undefined.
const bus = { plate: 'LAG-441-XA', seatsLeft: 9 };
console.log(bus.owner);
console.log(typeof bus.owner);
// So a plain if-check reads well:
if (bus.owner) {
console.log('Owner on file.');
} else {
console.log('No owner recorded.');
}
// And `in` answers the sharper question: is the key present at all?
console.log('owner' in bus);
console.log('seatsLeft' in bus);
Output
Objects change
Assign to a property that exists and you replace it. Assign to one that does not and you create it.
const bus = { plate: 'LAG-441-XA', seatsLeft: 9 };
bus.seatsLeft = 10; // changed
bus.owner = 'C. Okafor'; // created
delete bus.seatsLeft; // gone
console.log(bus);
console.log(Object.keys(bus));
console.log(Object.values(bus));
Output
Objects inside objects, objects inside arrays
A value can be anything, including another object or an array. That is how you describe something with real structure.
const bus = {
plate: 'LAG-441-XA',
body: {
seats: 14,
features: ['air conditioning', 'reclining seats', 'TV'],
},
today: {
route: 'Lagos - Abuja',
seatsLeft: 9,
},
};
console.log(bus.body.seats);
console.log(bus.body.features[0]);
console.log(bus.today.seatsLeft);
Output
And a whole park is an array of objects. This shape, a list of records, is most of the data you will ever handle.
const park = [
{ plate: 'LAG-441-XA', seatsLeft: 9, ready: true },
{ plate: 'ABJ-772-KM', seatsLeft: 6, ready: false },
{ plate: 'ENU-318-PH', seatsLeft: 11, ready: true },
];
for (const bus of park) {
console.log(bus.plate, '-', bus.seatsLeft, 'seats left');
}
const ready = park.filter(b => b.ready);
console.log('Ready to depart:', ready.map(b => b.plate));
const total = park.reduce((sum, b) => sum + b.seatsLeft, 0);
console.log('Seats still open across the park:', total);
Output
The one thing that surprises everybody
An object variable does not hold the object. It holds a reference to it, like a tag pointing at something parked in the yard. Copy the variable and you copy the tag, not the bus.
const original = { plate: 'LAG-441-XA', seatsLeft: 9 };
const alias = original;
alias.seatsLeft = 12;
console.log('original.seatsLeft is', original.seatsLeft);
console.log('Same object?', original === alias);
// A separate object with identical contents is still a different object.
const twin = { plate: 'LAG-441-XA', seatsLeft: 12 };
console.log('Equal contents, same object?', original === twin);
Output
const original = {
plate: 'LAG-441-XA',
body: { seats: 14 },
};
const shallow = { ...original };
shallow.plate = 'COPY-000-XX'; // own property, safe
shallow.body.seats = 99; // shared object, not safe
console.log('after shallow edit, original seats:', original.body.seats);
const deep = structuredClone(original);
deep.body.seats = 1;
console.log('after deep edit, original seats:', original.body.seats);
Output
Your turn: describe something real
Replace the bus below with something from your own life: a phone, a generator, a laptop, a recipe. Give it at least four properties, one of which is an array and one of which is a nested object. Then log two things out of it. Run it as often as you like; nothing here can break.
Output
Recap
- An object gathers named facts that belong together into one value.
obj.keyreads a property;obj['key']does the same when the key is dynamic or awkward.- A missing property is
undefined, not an error, and'key' in objasks whether it exists at all. constprotects the variable, never the contents.- Object variables hold references. Assignment shares;
{ ...obj }copies one level;structuredClone(obj)copies all of it.