I am creating a object using Object.create
and I want to add properties to it.
> var o = Object.create({});
undefined
> Object.defineProp
Properties defined through Object.defineProperty() are, by default, non-configurable.
To allow them to be redefined, or reconfigured, they have to be defined with this attribute set to true
.
var o = Object.create({});
Object.defineProperty(o, "foo", {
value: 42,
enumerable: true,
configurable: true
});
console.log(o); // { foo: 42 }
Object.defineProperty(o, "foo", {
value: 45,
enumerable: true,
configurable: true
});
console.log(o); // { foo: 45 }
o.prototype
is undefined
because objects don't typically have prototype
properties.
Such properties are found on constructor function
s for new
instances to inherit from, roughly equivalent to:
function Foo() {}
// ... = new Foo();
var bar = Object.create(Foo.prototype);
Foo.call(bar);
Object are, however, aware of their prototype objects. They're referenced through an internal [[Prototype]] property, which __proto__
is/was an unofficial getter/setter of:
console.log(o.__proto__); // {}
The standardized way to read the [[Prototype]]
is with Object.getPrototypeOf():
console.log(Object.getPrototypeOf(o)); // {}
Only when both writable and configurable are false, "Cannot redefine property" will happen.
If writable or configurable is true, the error will disappear.
"use strict"
var obj = {};
Object.defineProperty(obj, "name",
{
value: "Fundebug",
writable: false,
configurable: false
})
Object.defineProperty(obj, "name",
{
value: "云麒"
}) // “Uncaught TypeError: Cannot redefine property: name”
Therefore, jdphenix and Jonathan are not exactly correct.
You are unable to redefine the property because Object.defineProperty()
defaults to non-configurable properties, from the docs:
configurable
true if and only if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object. Defaults to false.
So this defaults to false - you'd need to pass it configurable: true
to allow it.
Object.defineProperty(o, "foo", {value: 43, enumerable: true});
This line defines property foo
on object o
with value:43 and attributes enumerable:true
, writable:false
, configurable:false
. If the property exists, defineProperty
updates its flags. Otherwise, it creates the property with the given value and flags; in that case, if a flag is not supplied, it is assumed false.
So, here we are making our property non-configurable as configurable
flag (or attribute) is false.
Making a property
non-configurable
is a one-way road. We cannot change it back withdefineProperty
.To be precise, non-configurability imposes several restrictions on defineProperty:
So be careful with configurable
flag in defineProperty
, always set it to true in defineProperty if you want to change enumerable and writable attributes(or flag). Once you set configurable false you cant set it to true.