Newsletter
Chapter 7 of 12

JavaScript objects: create, read, edit, iterate and delete properties

verified on 7 September 2026 · 7 min

Quick answer

A JavaScript object groups data as key–value pairs: const personne = { nom: 'Jean', age: 30 };. You read a property with personne.nom or personne['nom'], modify or add one with a plain assignment, delete one with delete, and iterate over the object with Object.keys(), Object.values() or Object.entries().

By the end of this chapter, you will be able to create an object, read and modify its properties, add and delete them, iterate over all its keys, work with nested objects and arrays of objects, and copy an object without side effects.

In the previous chapter, functions let us group instructions together. Objects group data: a user, a product or an API response are all objects. It is the structure you will handle most in JavaScript, and this chapter covers it end to end, from creation to copying.

What is an object in JavaScript?

An object is a set of properties, each made of a key (a name) and a value. The value can be of any type: a string, a number, a boolean, an array, another object or a function. If you know Python dictionaries or PHP associative arrays, the idea is the same.

app.js
const personne = {
  nom: 'Jean',
  age: 30,
  ville: 'Lille',
  actif: true,
  langues: ['français', 'anglais'],
};

The braces delimit the object, each property is written clé: valeur, and properties are separated by commas. A trailing comma after the last property is allowed and makes additions easier.

Creating an object

Literal notation

That is the one used in the example above, and it is the form to use in the vast majority of cases. An empty object is written {}, and you can fill it in afterwards:

javascript
const telephone = {};
telephone.marque = 'Sony';
telephone.prix = 400;
telephone.stock = 200;

console.log(telephone); // { marque: 'Sony', prix: 400, stock: 200 }

A constructor function

When you need several objects of the same shape, a function called with new builds them. Inside it, this refers to the object being created.

telephone.js
function Telephone(marque, prix, stock) {
  this.marque = marque;
  this.prix = prix;
  this.stock = stock;
  this.enStock = function () {
    return this.stock > 0;
  };
}

const motoZ = new Telephone('Motorola', 400, 200);
const miMax = new Telephone('Xiaomi', 200, 0);

console.log(motoZ.enStock()); // true
console.log(miMax.enStock()); // false

This style is the ancestor of classes, which you will meet later: class Telephone { constructor(marque, prix, stock) { … } } does the same thing with clearer syntax. You will still come across constructor functions in existing code.

Finally, new Object() also creates an empty object, but brings nothing over {}: it is no longer used.

Reading a property

Two syntaxes, equivalent in the simple case:

javascript
console.log(personne.nom);     // 'Jean'   : dot notation
console.log(personne['nom']);  // 'Jean'   : bracket notation

Brackets become essential in two situations: when the key is held in a variable, and when it contains characters that cannot follow a dot.

javascript
const cle = 'age';
console.log(personne[cle]);            // 30 : the key comes from a variable

const fiche = { 'prénom complet': 'Jean Dupont' };
console.log(fiche['prénom complet']);  // 'Jean Dupont' : a space in the key

Reading a property that does not exist raises no error: the result is undefined.

javascript
console.log(personne.pays);   // undefined

Reading a property of a missing property, however, crashes: personne.adresse.ville throws “Cannot read properties of undefined”. Optional chaining with ?. avoids the error:

javascript
console.log(personne.adresse?.ville);   // undefined, no error

Modifying and adding

The same assignment updates an existing property or creates a new one:

javascript
personne.age = 31;            // modification
personne.pays = 'France';     // addition: the property did not exist
personne['ville'] = 'Lyon';   // modification, bracket notation

console.log(personne.age, personne.pays, personne.ville);   // 31 'France' 'Lyon'

Mind const: it prevents reassigning the personne variable to another object, not modifying the object itself. That is intentional, and convenient. To forbid any modification, Object.freeze(personne) freezes the object (assignments are then ignored in non-strict mode and rejected in strict mode).

Deleting a property and testing whether it exists

javascript
delete personne.pays;

console.log(personne.pays);                 // undefined
console.log('pays' in personne);            // false : the key no longer exists
console.log(Object.hasOwn(personne, 'nom')); // true  : the key exists, as the object's own property

delete removes the property. To check whether a key is present, prefer in or Object.hasOwn() to a test against undefined: a property can exist with the value undefined.

Methods: functions inside an object

A property whose value is a function is called a method. Inside a method, this refers to the object that contains it.

app.js
const personne = {
  nom: 'Ana',
  naissance: 1996,
  saluer() {
    return `Salut, je suis ${this.nom}`;
  },
  age() {
    return 2026 - this.naissance;
  },
};

console.log(personne.saluer()); // 'Salut, je suis Ana'
console.log(personne.age());    // 30
No arrow functions here

age: () => 2026 - this.naissance does not work: an arrow function has no this of its own and cannot see the object. For a method, use the shorthand syntax age() { … } or age: function () { … }. The details of this are in the article bind, call and apply.

Iterating over an object

Three static methods return an object’s contents as an array, which lets you use everything you know about loops:

javascript
const produit = { nom: 'Clavier', prix: 49.9, stock: 12 };

console.log(Object.keys(produit));    // ['nom', 'prix', 'stock']
console.log(Object.values(produit));  // ['Clavier', 49.9, 12]
console.log(Object.entries(produit)); // [['nom', 'Clavier'], ['prix', 49.9], ['stock', 12]]

for (const [cle, valeur] of Object.entries(produit)) {
  console.log(`${cle} : ${valeur}`);
}
// nom : Clavier
// prix : 49.9
// stock : 12

console.log(Object.keys(produit).length);   // 3 : the “number of properties”

The for…in loop also exists and goes through the keys directly. It does, however, pick up properties inherited from the prototype, which is surprising as soon as you handle objects created by libraries: Object.keys() with for…of is the default choice.

javascript
for (const cle in produit) {
  console.log(cle);   // nom, prix, stock
}

The reverse operation, rebuilding an object from pairs, is done with Object.fromEntries():

javascript
Object.fromEntries([['a', 1], ['b', 2]]);   // { a: 1, b: 2 }

Nested objects and arrays of objects

A value can be an object: that is how you represent a structure. And an array of objects is the most common shape for data coming from an API.

commande.js
const commande = {
  numero: 1042,
  client: {
    nom: 'Jean',
    adresse: { ville: 'Lille', codePostal: '59000' },
  },
  lignes: [
    { produit: 'Clavier', prix: 49.9, quantite: 1 },
    { produit: 'Souris', prix: 19.5, quantite: 2 },
  ],
};

console.log(commande.client.adresse.ville);   // 'Lille'
console.log(commande.lignes[1].produit);      // 'Souris'

let total = 0;
for (const ligne of commande.lignes) {
  total += ligne.prix * ligne.quantite;
}
console.log(total);   // 88.9

Data from a server arrives as JSON text, whose syntax is that of object literals: JSON.parse(texte) turns it into an object, and JSON.stringify(objet) does the reverse.

Copying an object without surprises

Assigning an object to another variable does not copy it: both variables point to the same object in memory.

javascript
const original = { nom: 'Jean', adresse: { ville: 'Paris' } };

const alias = original;
alias.nom = 'Paul';
console.log(original.nom);   // 'Paul' : it was not a copy

The spread operator copies the first level, but nested objects remain shared:

javascript
const copie = { ...original };
copie.nom = 'Marie';
copie.adresse.ville = 'Lyon';

console.log(original.nom);            // 'Paul'  : the first level was copied
console.log(original.adresse.ville);  // 'Lyon'  : the nested object is shared

For a complete copy, independent at every level, structuredClone() is the function designed for the job:

javascript
const clone = structuredClone(original);
clone.adresse.ville = 'Nice';

console.log(original.adresse.ville);  // 'Lyon' : the original has not changed

structuredClone does not copy methods: keep it for data objects. Finally, Object.assign(cible, source) merges objects, with the same shallow copy as the spread operator.

Summary

Need Syntax
Create const o = { cle: valeur };
Read o.cle, o['cle'], o.a?.b
Modify or add o.cle = valeur;
Delete, test delete o.cle; then 'cle' in o
Iterate Object.keys(o), Object.values(o), Object.entries(o)
Copy { ...o } (one level), structuredClone(o) (complete)

Towards object-oriented programming

When several objects share the same shape and the same methods, you describe them once in a class and create instances with new. That is the natural follow-up to this chapter: Classes in JavaScript and Introduction to classes and objects (ES6). For now, the next chapter introduces an object provided by the language, Math, and its methods.

ExerciseCreate a livre object with a title, an author and a year, add a lu property set to false, then write a resume(livre) function that returns “Title (Author, year) — read” or “— unread”. Finally, put three books in an array and display only those that have been read.

Common errors

An arrow function as a method { age: 30, calc: () => 2026 - this.age } does not work: an arrow function has no this. Write the method in shorthand syntax, calc() { return 2026 - this.age; }.
Copying with = const copie = original; copies nothing: both variables refer to the same object, and changing one changes the other. Use { ...original } or structuredClone(original).
Shallow copies { ...original } copies the first level only: a nested object is still shared. For a complete copy, use structuredClone().
const does not freeze the object const o = {}; o.a = 1; is valid: const forbids reassigning the variable, not modifying the object. To freeze it, use Object.freeze(o).
Newsletter

New tests, tutorials and projects, by e-mail.

Reproducible tests, versioned code, dated results. Never any spam.