Last updated: Mar 7, 2024
Reading time·3 min
The JavaScript "TypeError: Cannot redefine property: X" occurs when you attempt to redefine a property that is not configurable.
To solve the error, set the configurable
property to true
when calling the
Object.defineProperty()
method.
Here is an example of how the error occurs.
const obj = Object.create({}); Object.defineProperty(obj, 'site', {value: 'bobbyhadz.com'}); // ⛔️ TypeError: Cannot redefine property: site // at Function.defineProperty (<anonymous>) Object.defineProperty(obj, 'site', {value: 'google.com'});
The issue in the code sample is that by default, properties created using
Object.defineProperty()
are not configurable.
In other words, they cannot be deleted or changed.
configurable
property to true
To solve the error, set the configurable
property to true
in the call to the
Object.defineProperty()
method.
// ✅ Works as expected const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', configurable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', configurable: true, }); console.log(obj.site); // 👉️ google.com
The Object.create()
method creates a new object using an existing object as
its prototype.
The Object.defineProperty()
method adds a new property to an object or
modifies an existing property on the object.
The method takes the following 3 arguments:
Name | Description |
---|---|
obj | The object on which to define the property |
prop | The name of the property |
descriptor | THe descriptor for the property that is being defined or modified |
You can set the following properties on the descriptor
object:
Name | Description |
---|---|
enumerable | If true , the property is iterated over in loops. Defaults to false . |
configurable | If false , the property cannot be deleted or changed. Defaults to false . |
writable | If false , the value of the property cannot be changed |
As shown in the code sample, when the configurable
property is set to true
,
the property can be modified.
const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', configurable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', configurable: true, }); console.log(obj.site); // 👉️ google.com
When the configurable
property is set to true
, the property can also be
deleted.
const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', configurable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', configurable: true, }); delete obj['site']; console.log(obj.site); // 👉️ undefined
In some cases, you might want to be able to modify the property but not to delete it.
When the writable
property is set to true
, the value of the property can be
changed.
By default, the property is set to false
, just like the configurable
property.
The difference between the two properties is that setting writable
to true
doesn't allow you to delete the property.
const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', writable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', writable: true, }); console.log(obj.site); // 👉️ google.com // ⛔️ TypeError: Cannot delete property 'site' of #<Object> delete obj['site'];
Notice that an error is raised when you attempt to delete a property with only
writable
set to true
.
This is not the case when configurable
is set to true
.
const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', configurable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', configurable: true, }); delete obj['site']; console.log(obj.site); // 👉️ undefined
You can also set the enumerable
property to true
if you need to be able to
iterate over the property in loops.
const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', configurable: true, enumerable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', configurable: true, enumerable: true, }); for (const key in obj) { console.log(key, obj[key]); // 👉️ site, google.com } console.log(obj.site); // 👉️ google.com
The enumerable
property defaults to false
.
You can learn more about the related topics by checking out the following tutorials: