'Disallow setting New or Undeclared property in an object

Suppose I have a JavaScript object with some properties.

var properties = {
    x : 10,
    y : 20,
    z : 30,
};

Here, I declared and defined the properties x, y, and z. Thus I can access them using properties.x, properties.y, properties.z respectively.

Suppose I now try to set another property that I haven't declared.

properties.foo = 100;

It turns out this is allowed, and properties.foo is now defined to be 100.

However, since I never declared foo in var properties = { ... }, I would like to make it so that when someone attempts to set foo, an Exception is thrown.

Or more generally, I would like to throw an exception when someone attempts to set any property that I did not initially declare in var properties = { ... }.

Is this possible?

Ideally, I should still be able to change properties that I previously set. Thus, I should still be able to do properties.x = 40; without any problems.

My motivate for wanting to do so is to prevent making a typo when changing existing properties. For example, I intend to set properties.x = 40 but accidentally wrote properties.c = 40. This may have undesired effects and/or induces debugging headaches.


Here is an example in jsfiddle.

var properties = {
    x : 10,
    y : 20,
    z : 30,
};

console.log(properties.x); // ok, logs 10
console.log(properties.y); // ok, logs 20
console.log(properties.z); // ok, logs 30

properties.foo = 100; // should not be ok, because there is no foo in properties.

properties.x = 40; // should be ok.
console.log(properties.x); // ok, logs 40

console.log(properties.foo); // logs 100, but should be undefined.


Solution 1:[1]

Use Object.preventExtensions(). Existing properties can still be modified, but any attempt to add a new one will throw a TypeError.

let properties = Object.preventExtensions({
  x : 10,
  y : 20,
  z : 30,
})

properties.x = 40 // 40
properties.c = 40 // TypeError: Cannot add property c, object is not extensible

Note that properties can still be deleted.

delete properties.x // {y: 20, z: 30}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nate Pickens