The previous lesson built skill cards from a string array. This lesson introduces objects: values with labeled fields. You drive the header from a profile object, then upgrade each skill to an object and read skill.name in the loop.
The concept
Here is your page with cards rendered from string skills. Run it:
▸WHAT'S ALREADY IN THIS PAGE
New here? This starter already carries the standard HTML frame. You do not need to change it to do the exercise — each piece is taught in its own lesson.
<!DOCTYPE html>— Tells the browser to use modern rendering rules. Taught in lesson 2.<html> … </html>— The root element that wraps the whole document. Taught in lesson 2.lang="en"— Sets the page's language. Taught in lesson 6.<head>— Holds information about the page; nothing in it is drawn on screen. Taught in lesson 2.<meta charset="UTF-8" />— Sets how the browser decodes the text. Taught in lesson 6.<title>— Sets the browser-tab text. Taught in lesson 2.<body>— Holds everything a visitor actually sees. Taught in lesson 2.<script>— Holds JavaScript for the page. Taught in lesson 23.
The cards still come from strings. The heading and tagline still use separate values. You are about to group labeled data.
Run this and watch the CONSOLE:
▸WHAT'S ALREADY IN THIS PAGE
New here? This starter already carries the standard HTML frame. You do not need to change it to do the exercise — each piece is taught in its own lesson.
<!DOCTYPE html>— Tells the browser to use modern rendering rules. Taught in lesson 2.<html> … </html>— The root element that wraps the whole document. Taught in lesson 2.lang="en"— Sets the page's language. Taught in lesson 6.<head>— Holds information about the page; nothing in it is drawn on screen. Taught in lesson 2.<meta charset="UTF-8" />— Sets how the browser decodes the text. Taught in lesson 6.<title>— Sets the browser-tab text. Taught in lesson 2.<body>— Holds everything a visitor actually sees. Taught in lesson 2.<script>— Holds JavaScript for the page. Taught in lesson 23.
The CONSOLE shows Your Name, then Learner. Curly braces hold fields. Each field, officially a property, has a name on the left and a value on the right. CSS declarations had properties too; JavaScript reuses the word for the same shape, a name on the left and a value on the right. The whole curly-brace value is an object.
Read a field with a dot: profile.name.
Drive the header from one object:
▸WHAT'S ALREADY IN THIS PAGE
New here? This starter already carries the standard HTML frame. You do not need to change it to do the exercise — each piece is taught in its own lesson.
<!DOCTYPE html>— Tells the browser to use modern rendering rules. Taught in lesson 2.<html> … </html>— The root element that wraps the whole document. Taught in lesson 2.lang="en"— Sets the page's language. Taught in lesson 6.<head>— Holds information about the page; nothing in it is drawn on screen. Taught in lesson 2.<meta charset="UTF-8" />— Sets how the browser decodes the text. Taught in lesson 6.<title>— Sets the browser-tab text. Taught in lesson 2.<body>— Holds everything a visitor actually sees. Taught in lesson 2.<script>— Holds JavaScript for the page. Taught in lesson 23.
The heading and tagline both come from profile. Change the object, and both update from the same place.
Now upgrade the skills list so each item is an object, and the card text uses skill.name:
▸WHAT'S ALREADY IN THIS PAGE
New here? This starter already carries the standard HTML frame. You do not need to change it to do the exercise — each piece is taught in its own lesson.
<!DOCTYPE html>— Tells the browser to use modern rendering rules. Taught in lesson 2.<html> … </html>— The root element that wraps the whole document. Taught in lesson 2.lang="en"— Sets the page's language. Taught in lesson 6.<head>— Holds information about the page; nothing in it is drawn on screen. Taught in lesson 2.<meta charset="UTF-8" />— Sets how the browser decodes the text. Taught in lesson 6.<title>— Sets the browser-tab text. Taught in lesson 2.<body>— Holds everything a visitor actually sees. Taught in lesson 2.<script>— Holds JavaScript for the page. Taught in lesson 23.
for (const skill of skills) still walks the array. Now skill is an object, so the label is skill.name. A role field can sit beside name for later use even if the card only shows the name today.
The syntax
const profile = {
name: "Your Name",
tagline: "Building things for the web",
};
const skills = [
{ name: "HTML", role: "Structure" },
{ name: "CSS", role: "Look" },
{ name: "JavaScript", role: "Behaviour" },
];
for (const skill of skills) {
item.textContent = skill.name;
}{ key: value } creates an object. Each field is officially a property.
object.key reads one property.
When array items are objects, the loop variable is an object. Read the property you need.
A minimal working example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Objects</title>
<style>
.tagline.is-set {
color: teal;
font-weight: 600;
}
.skill-card {
padding: 0.5rem;
}
</style>
</head>
<body>
<h1></h1>
<p class="tagline"></p>
<ul class="skill-row"></ul>
<script>
function setTagline(text) {
const tagline = document.querySelector(".tagline");
tagline.textContent = text;
tagline.classList.add("is-set");
}
const profile = {
name: "Your Name",
tagline: "Building things for the web",
};
document.querySelector("h1").textContent = profile.name;
setTagline(profile.tagline);
const skills = [
{ name: "HTML", role: "Structure" },
{ name: "CSS", role: "Look" },
{ name: "JavaScript", role: "Behaviour" },
];
const skillRow = document.querySelector(".skill-row");
for (const skill of skills) {
const item = document.createElement("li");
item.classList.add("skill-card");
item.textContent = skill.name;
skillRow.append(item);
}
</script>
</body>
</html>One profile object for the header. One skills array of objects. The loop reads skill.name.
Common mistakes
You set textContent to the whole object. Run this:
▸WHAT'S ALREADY IN THIS PAGE
New here? This starter already carries the standard HTML frame. You do not need to change it to do the exercise — each piece is taught in its own lesson.
<!DOCTYPE html>— Tells the browser to use modern rendering rules. Taught in lesson 2.<html> … </html>— The root element that wraps the whole document. Taught in lesson 2.lang="en"— Sets the page's language. Taught in lesson 6.<head>— Holds information about the page; nothing in it is drawn on screen. Taught in lesson 2.<meta charset="UTF-8" />— Sets how the browser decodes the text. Taught in lesson 6.<title>— Sets the browser-tab text. Taught in lesson 2.<body>— Holds everything a visitor actually sees. Taught in lesson 2.<script>— Holds JavaScript for the page. Taught in lesson 23.
The card does not show HTML. It shows a default object string such as [object Object]. After the upgrade, skill is an object. Use skill.name.
You mistype the property name. You write skill.Name or skill.title while the object uses name. The card is blank or shows undefined. Property names are exact. Match the key you wrote in the object literal.
You upgrade the array but leave textContent = skill from the string version. The loop still runs. The cards show a default object string such as [object Object] instead of HTML. When each item becomes an object, update the line that chooses the visible text to skill.name.
Try it yourself
Drive the header from a profile object, then upgrade skills to objects. Confirm each step in the preview. The header stays above the fold. After each Run that asks about the skill cards, scroll the preview to Skills if you do not see them yet.
- Run the starting code below. Scroll the preview to Skills if you do not see it yet. Confirm the skill cards still render from the string array. Confirm the buttons still work.
- Near the top of the script (above or beside your tagline helpers), add a
profileobject with at leastnameandtaglinestring fields. Select theh1and set itstextContenttoprofile.name. CallsetTagline(profile.tagline)instead of the hard-coded first tagline string (keep the change-tagline button on its own alternate string). Run it. Confirm the header still shows your name and tagline. - Change the
skillsarray from strings to objects. Each object needs anamefield (addroleif you want a second label). Run it once before fixing the loop if you like, and notice the cards break. - In the
for (const skill of skills)loop, setitem.textContent = skill.name. Run it. Scroll to Skills. Confirm three cards show the skill names again. - Break it on purpose: set
textContentback toskill(the whole object). Run it. Scroll to Skills. Confirm the cards no longer show clean labels. Putskill.nameback and confirm the names return. - Retire the early scaffolding: delete
const pageOwner,const skillCount, and the fourconsole.loglines that printpageOwner,skillCount,skills.length, andskills[0]. Those opened the act and checked length by hand;skills.lengthalready counts, and the cards show the list. Run it. Confirm the page still works and the CONSOLE no longer prints those four lines.
▸WHAT'S ALREADY IN THIS PAGE
New here? This starter already carries the standard HTML frame. You do not need to change it to do the exercise — each piece is taught in its own lesson.
<!DOCTYPE html>— Tells the browser to use modern rendering rules. Taught in lesson 2.<html> … </html>— The root element that wraps the whole document. Taught in lesson 2.lang="en"— Sets the page's language. Taught in lesson 6.<head>— Holds information about the page; nothing in it is drawn on screen. Taught in lesson 2.<meta charset="UTF-8" />— Sets how the browser decodes the text. Taught in lesson 6.<title>— Sets the browser-tab text. Taught in lesson 2.<body>— Holds everything a visitor actually sees. Taught in lesson 2.<script>— Holds JavaScript for the page. Taught in lesson 23.
Your page now keeps labeled data in objects, and the skill loop practises skill.name. The early console scaffolding is gone. The next lesson reads what someone types into the contact form and answers on the page.