JavaScript Objects
A JavaScript object, in a nutshell, is a data structure to hold key-value pairs. But unlike a simple map or dictionary, JavaScript objects are highly configurable. In this lesson, we are going to learn about the “property descriptor” which holds the configurations of an object’s property.

When we create a JavaScript object, whether using object literal syntax or some other means and add some properties to it, each property (key) gets a default property descriptor. A property descriptor is a simple JavaScript object associated with each property of the object that contains information about that property such as its value and other meta-data.

In the above example, we have created a plain JavaScript object myObj using literal syntax with myPropOne and myPropTwo properties. We have given these properties some initial values, viz. 1 and 2 respectively.
Now, if we write a new value to myPropOne property like below, the operation will be successful and we will get the changed value.

To access the property descriptor of property, we need to use a static method provided by the Object. The Object.getOwnPropertyDescriptor method returns the property descriptor of the prop which is the property name on the obj object.
Object.getOwnPropertyDescriptor(obj, prop);
Own here means return the property descriptor of prop property only if that property belongs to the object obj and not on its prototype chain. If the property prop doesn’t exist on obj, it returns undefined.
💡 If you want to know what prototype or prototype chain is, read my lesson on JavaScript’s prototype-based inheritance.

The Object.getOwnPropertyDescriptor method returns an object with keys describing the setting and current value of the property. The value property of the property descriptor is the current value of the property, writable is whether the user can assign a new value to the property, enumerable is whether this property will show up in enumerations like for in loop or for of loop or Object.keys etc.
The configurable property tells whether the user has permission to change property descriptor such as to change the value of writable and enumerable settings.
💡 Property descriptor also has get and set keys as well which are middleware functions to return value or update value, but these are optional.
To create a new property on an object or update existing property with a custom descriptor, we use Object.defineProperty. Let’s modify an existing property myPropOne with writable set to false, which should disable writes to myObj.myPropOne.

As you can see from the above error, our property myPropOne is not writable, hence if a user is trying to assign a new value to it, it will throw an error.
💡 If Object.defineProperty is updating existing property descriptor, then original descriptor will be merged with new modifications. Object.defineProperty returns the original object myObj after changes.
Let’s see what will happen if we set enumerable descriptor key to false.

As you can see from the above result, we can’t see myPropOne property of the object in Object.keys enumeration.
When you define a new property on object using Object.defineProperty and pass empty {} descriptor, the default descriptor looks like below.
{
value: undefined,
writable: true,
enumerable: false,
configurable: false
}
Now, let’s define a new property with custom descriptor where configurable descriptor key is set to false. We will keep writable to false and enumerable to true with value set to 3.

By setting configurable descriptor key to false, we lost the ability to change descriptor of our property myPropThree. This is very helpful if you don’t want your users to manipulate the recommended behavior of an object.
get (getter) and set (setter) for a property can also be set in property descriptor with these exact keys. But when you define a getter, it comes with some sacrifices. You can not have an initial value or value key on the descriptor at all because the getter will return the value of that property. You can not use writable key on descriptor as well, because your writes are done through the setter and you can prevent writes there. Have a look at MDN documentation of getter and setter.
💡 You can create and/or update multiple properties at once using Object.defineProperties which takes two arguments. First argument is target object on which properties has to be added/modified and second argument is object with key as property name and value as its property descriptor. This function returns the target object.
Have you tried Object.create function to create objects? This is the easiest way to create an Object with no or a custom prototype. It is also one of the easier ways to create objects from scratch with custom property descriptors.
Object.create function has the following syntax.
var obj = Object.create( prototype, { property: descriptor, ... } )
Here prototype is an object which will be the prototype of the obj. If prototype is null, then obj won’t have any prototype. When you define an empty or non-empty object with var obj= {} syntax, by default, obj.__proto__ points to Object.prototype hence obj has the prototype of Object class.
This is similar to using Object.create with Object.prototype as the first argument (prototype of the object being created).


But when we set the prototype to null, we get below error.


A quick introduction to the “Property Descriptor” of the JavaScript objects was originally published in JsPoint on Medium, where people are continuing the conversation by highlighting and responding to this story.