Javascript Object.defineProperties()

The Object.defineProperties() method adds or modifies properties on an object and returns the object.

Example

// create an object obj
let obj = {};

// define multiple properties of the obj object Object.defineProperties(obj, { property1: { value: true, writable: true, }, property2: { value: "Hello", writable: false, }, });
console.log(obj.property1); // true console.log(obj.property2); // Hello

defineProperties() Syntax

The syntax of the defineProperties() method is:

Object.defineProperties(obj, props)

Here, defineProperties() is a static method. Hence, we need to access the method using the class name, Object.


defineProperties() Parameters

The defineProperties() method takes in:

  • obj - the object on which to define or modify properties.
  • props - objects whose keys represent the names of the properties to be defined or modified, and whose values are objects describing those properties.

defineProperties() Return Value

The defineProperties() method returns the object that was passed as an argument i.e. obj.

Note: If a descriptor doesn't contain any of the value, writable, get and set keys, then it is treated as a data descriptor. An exception is thrown if a descriptor has both value or writable and get or set keys.


Example 1: JavaScript Object.defineProperties()

let obj1 = {};

// define two properties for obj1 Object.defineProperties(obj1, { 'name': { value: 'Clint', writable: true }, 'age': { value: 36, writable: true } });
// print name property of obj1 console.log(obj1.name) // print age of obj1 console.log(obj1.age)

Output

Clint
36

In this example, we have used Object.defineProperties() to add the name and age properties to obj1. The properties are defined with specific values and with their writable attributes set to true.

The output indicates that name and age have been added to obj1 successfully.


defineProperties() Props Values

Before proceeding further, let's first discuss the possible values the props parameters can have.

Each property value must either be a data descriptor or an accessor descriptor. They can have the following optional properties:

  • configurable - the ability to change or delete a property's attributes
  • enumerable - the property that is visible in for...in loops and with Object.keys().

Data descriptors can also have:

  • value - the actual data stored in a property, accessible through its key.
  • writable - the ability to change the value of a property. If false, the property's value cannot be changed.

Accessor descriptors can also have:

  • get - a function that returns the property's value.
  • set - a function that sets the property's value.

Example 2: defineProperties() With Data Descriptors

let obj = {};

// define the object's properties using
// data descriptors value and writable
Object.defineProperties(obj, {
  "id": {
value: 711, writable: false
}, "email": {
value: "hello@test.com", writable: true
} }); // print the original properties of obj console.log("Original Properties:"); console.log("id: " + obj.id); console.log("email: " + obj.email); console.log("\nChanged Properties:"); // attempt to change unwritable property id // change will fail silently obj.id = 358; // print id property again console.log("id: " + obj.id); // try to change the writable property email // email value gets changed obj.email = "world@test.com"; // print email property again console.log("email: " + obj.email);

Output

Original Properties:
id: 711
email: hello@test.com

Changed Properties:
id: 711
email: world@test.com

In the above example, we first created an empty object obj.

Then, we used Object.defineProperties to add two properties to obj: id and email. For each property, we defined its value and whether it's writable or not.

Later, we tried to see how the writable data descriptor works.

// attempt to rewrite unwritable property id
obj.id = 358;
console.log(obj.id); // 711

However, the writable data descriptor of id has been set to false. So, we are unable to rewrite the id property.

We then tried to modify the email property.

// attempt to rewrite writable property email
obj.email = "world@test.com";
console.log(obj.email);

We are able to rewrite the email property because its data descriptor writable was set to true.


Example 3: defineProperties() With Access Descriptors

const obj = {};

// define object properties using
// access descriptors get and set
Object.defineProperties(obj, {
  prop1: {
get: function() { return this._prop1; }, set: function(val) { this._prop1 = val; },
enumerable: true, configurable: true }, prop2: {
get: function() { return this._prop2; }, set: function(val) { this._prop2 = val; },
enumerable: true, configurable: false } }); // set the value of prop1 and print it obj.prop1 = "Hello"; console.log(obj.prop1); // Output: Hello // set the value of prop2 and print it obj.prop2 = "World"; console.log(obj.prop2); // Output: World

In the above example, we have defined two properties, prop1 and prop2, on the obj object using Object.defineProperties(). Both properties have the following access descriptors:

  • set - a method that allows us to set the value of the property
  • get - a method that allows us to retrieve the value of the property

Recommended Reading: