One common approach for tagging variables as “private” is through variable naming conventions like _ or $$ prefixes. However, the problem with conventions is that there is always the chance that something will be overwritten inadvertently.
Object.defineProperty changes how we define properties by giving us granular control over the behavior of the property. When using Object.defineProperty, properties are defined using a meta object that describes some behavioral attributes of the property. Basically, we have control over writability, initial value, enumerability and configurability. The meta object contains properties for controlling this behavior.
Value is the simplest one to understand – basically it's how we give the property an initial value.
Perhaps the most useful feature is the ability to define constants that can't be reset from code after the initial declaration. In the example below I will demonstrate how to create a constant by setting the writable attribute to false. Any attempt to write to a read-only property will not update the property and fail silently.
There is however a caveat here. Even though the property can't be overwritten – it still isn't immutable.
As you can see from the code below we are not able to reassign the property to a new object, but we are still able to change sub properties on the property.
Enumerability lets us specify if we want the property to be visible to a for-in loop. As you can see below setting this attribute to false hides it from the enumeration.
Configurable allows us to specify if we want to allow the property to be reconfigured by calling Object.defineProperty again – with new meta values.
Here's an example of how to use 'configurable'