Developer Question:

What is the difference between defineProperty and set using Reflect?

At first I thought that Reflect.set() was to modify the value of a property of an object but when I did the article on how i use Reflect with object properties, I came to the conclusion that it Reflect.definesProperty() and Reflect.set() do almost the same but with some differences.

Let’s talk about defining a property with both methods.

let myObj = {}; Reflect.defineProperty(myObj, "name", {

value: "John"

}); console.log(myObj.name); // John Reflect.set(myObj, "lastName", "Travolta"); console.log(myObj.lastName); // Travolta

So far so good, but what if we want to delete those properties ?

let myObj = {}; Reflect.defineProperty(myObj, "name", {

value: "John"

}); console.log(myObj.name); // John // Delete property name Reflect.deleteProperty(myObj, "name"); console.log(myObj.name); // John Reflect.set(myObj, "lastName", "Travolta"); console.log(myObj.lastName); // Travolta // Delete property lastName Reflect.deleteProperty(myObj, "lastName"); console.log(myObj.name); // undefined

What I have discovered is that in Reflect.set() the property is deleted perfectly but in Reflect.defineProperty() not.

Why ?

Reflect.defineProperty() is the same as Object.defineProperty() so let’s look at the MDN documentation again and discover the following,

By default, values added using Object.defineProperty() are immutable. Click to tweet.

The default values when defining a property with Reflect.defineProperty() similar to are immutable so we can’t delete them.

So how do we do it?

Let’s talk about the third argument of the function defineProperty is descriptor.

Property descriptors present in objects come in two main flavors: data descriptors and accessor descriptors.

In our particular case we are interested in the data, so we are going to explain data descriptors. It can have four values.

Configurable. If and only if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object. Default: false. Enumerable. If and only if this property shows up during enumeration of the properties on the corresponding object. Default: false. Value. The value associated with the property. Can be any valid JavaScript value. Default: undefined. Writable. If and only if the value associated with the property may be changed with an assignment operator. Default: false.

Only Reflect.defineProperty() is configurable in this manner, allowing you to change those defaults, while Reflect.set() is not.

So let´s back to the example and just add the configurable property to our object and see what happens.

let myObj = {}; Reflect.defineProperty(myObj, "name", {

value: "John",

configurable: true

}); console.log(myObj.name); // John // Delete property name Reflect.deleteProperty(myObj, "name"); console.log(myObj.name); // undefined Reflect.set(myObj, "lastName", "Travolta"); console.log(myObj.lastName); // Travolta // Delete property lastName Reflect.deleteProperty(myObj, "lastName"); console.log(myObj.name); // undefined