Home » JavaScript Object Protection: A Complete Tutorial with Examples

JavaScript Object Protection: A Complete Tutorial with Examples

In JavaScript, object protection involves restricting the ability to modify, add, or delete properties in an object.

This can be particularly useful when you want to ensure that certain objects remain consistent throughout your application, preventing accidental or malicious alterations.

JavaScript provides several built-in methods to protect objects:

Object.preventExtensions()
Object.seal()
Object.freeze()

In this tutorial, we’ll explore each of these methods, how they work, and provide examples to illustrate their usage.

1. Object.preventExtensions()

Object.preventExtensions() prevents new properties from being added to an object. However, it allows existing properties to be modified or deleted.

Example 1: Using Object.preventExtensions()

let car = {
  brand: 'Toyota',
  model: 'Corolla'
};

Object.preventExtensions(car);

// Attempting to add a new property
car.year = 2022;
console.log(car.year); // Output: undefined (addition failed)

// Modifying an existing property
car.model = 'Camry';
console.log(car.model); // Output: Camry

// Deleting an existing property
delete car.brand;
console.log(car); // Output: { model: 'Camry' }

Explanation

Object.preventExtensions(car) prevents adding new properties (car.year fails).
Modifying (car.model = ‘Camry') and deleting (delete car.brand) existing properties are still allowed.
Checking If an Object is Not Extensible

You can check if an object is non-extensible using Object.isExtensible().

console.log(Object.isExtensible(car)); // Output: false

2. Object.seal()

Object.seal() prevents adding or deleting properties to an object. However, it allows modifying the values of existing properties. In addition, it marks all existing properties as non-configurable, which means their descriptors (e.g., enumerability, configurability) cannot be changed.

Example 2: Using Object.seal()

let user = {
  name: 'Alice',
  age: 30
};

Object.seal(user);

// Attempting to add a new property
user.email = 'alice@example.com';
console.log(user.email); // Output: undefined (addition failed)

// Modifying an existing property
user.age = 31;
console.log(user.age); // Output: 31

// Attempting to delete a property
delete user.name;
console.log(user.name); // Output: Alice (deletion failed)

Explanation

Object.seal(user) prevents adding (user.email) and deleting (delete user.name) properties.
Modifying existing properties (user.age) is still allowed.

Checking If an Object is Sealed

You can check if an object is sealed using Object.isSealed().

console.log(Object.isSealed(user)); // Output: true

3. Object.freeze()

Object.freeze() is the most restrictive of the three methods. It prevents adding, deleting, or modifying properties of an object. Additionally, it marks all properties as non-writable and non-configurable.

Example 3: Using Object.freeze()

let book = {
  title: 'JavaScript Essentials',
  author: 'John Doe'
};

Object.freeze(book);

// Attempting to add a new property
book.year = 2023;
console.log(book.year); // Output: undefined (addition failed)

// Attempting to modify an existing property
book.title = 'Advanced JavaScript';
console.log(book.title); // Output: JavaScript Essentials (modification failed)

// Attempting to delete a property
delete book.author;
console.log(book.author); // Output: John Doe (deletion failed)

Explanation

Object.freeze(book) prevents adding (book.year), modifying (book.title), and deleting (delete book.author) properties.
Checking If an Object is Frozen

You can check if an object is frozen using Object.isFrozen().

console.log(Object.isFrozen(book)); // Output: true

4. Property Attributes and Protection Methods

When using Object.preventExtensions(), Object.seal(), and Object.freeze(), it's helpful to understand how they interact with property attributes like writable and configurable.

Summary of Protection Methods

Method Add Properties Delete Properties Modify Properties Change Property Attributes
Object.preventExtensions ❌ No ✅ Yes ✅ Yes ✅ Yes
Object.seal ❌ No ❌ No ✅ Yes ❌ No
Object.freeze ❌ No ❌ No ❌ No ❌ No

 

5. Protecting Nested Objects

Object.freeze() and Object.seal() do not perform deep protection. They only apply to the object at the top level, not nested objects.

Example 4: Protecting Nested Objects

let user = {
  name: 'Alice',
  address: {
    city: 'New York',
    zip: '10001'
  }
};

Object.freeze(user);

// Attempting to modify a nested object property
user.address.city = 'Los Angeles';
console.log(user.address.city); // Output: Los Angeles (modification succeeded)

Explanation

Even though Object.freeze(user) freezes the user object, the nested address object remains mutable.
To deeply freeze an object, you need to create a utility function.

Example 5: Deep Freezing an Object

function deepFreeze(obj) {
  // Retrieve the property names defined on obj
  let propNames = Object.getOwnPropertyNames(obj);

  // Freeze properties before freezing self
  for (let name of propNames) {
    let value = obj[name];

    // If value is an object, freeze it
    if (value && typeof value === 'object') {
      deepFreeze(value);
    }
  }

  return Object.freeze(obj);
}

let user = {
  name: 'Alice',
  address: {
    city: 'New York',
    zip: '10001'
  }
};

deepFreeze(user);

// Attempting to modify a nested object property
user.address.city = 'Los Angeles';
console.log(user.address.city); // Output: New York (modification failed)

Explanation

The deepFreeze() function recursively freezes the properties of an object, including nested objects.
After using deepFreeze(), attempts to modify nested properties are also prevented.

6. Working with Property Descriptors

You can use Object.defineProperty() to set property attributes like writable, enumerable, and configurable, providing more control over how individual properties can be accessed or modified.

Example 6: Using Object.defineProperty() for Property Protection

let user = {};
Object.defineProperty(user, 'name', {
  value: 'Alice',
  writable: false, // Cannot be modified
  enumerable: true,
  configurable: false // Cannot be deleted
});

console.log(user.name); // Output: Alice
user.name = 'Bob'; // Attempt to modify (fails silently)
console.log(user.name); // Output: Alice

delete user.name; // Attempt to delete (fails silently)
console.log(user.name); // Output: Alice

Explanation

writable: false makes the property read-only.
configurable: false makes the property non-deletable and prevents its descriptor from being modified.

Summary

Object protection in JavaScript helps to control how and if an object's properties can be modified, added, or deleted. Here is a quick overview of the methods:

Methods for Object Protection

Method Description
Object.preventExtensions() Prevents new properties from being added to the object.
Object.seal() Prevents adding or deleting properties; allows modification of existing properties.
Object.freeze() Prevents adding, deleting, or modifying properties.

Additional Tips

  • Use Object.isExtensible(), Object.isSealed(), and Object.isFrozen() to check the state of an object.
  • For deeply nested objects, use a custom function (e.g., deepFreeze()) to apply protection to all levels.
  • Utilize Object.defineProperty() to set property attributes (writable, enumerable, configurable) for more granular control.

By understanding and using these methods, you can ensure that your objects are safeguarded against unwanted changes, making your JavaScript applications more robust and reliable.

You may also like