Why can't I redefine a property in a Javascript object?


Why can't I redefine a property in a Javascript object?



I am creating a object using Object.create and I want to add properties to it.


Object.create


> var o = Object.create({});
undefined

> Object.defineProperty(o, "foo", {value: 43, enumerable: true});
{foo: 43}

> o
{foo: 43}

> o.foo
43

> for (var i in o) { console.log(i); }
foo

> Object.keys(o)
['foo']

> Object.defineProperty(o, "foo", {value: 43, enumerable: false });
TypeError: Cannot redefine property: bar



Q1) Why can't I redefine the property ?


> o.__proto__
{}

> o.prototype
undefined



Q2) Why is the prototype empty ? And why are these 2 values different i.e. {} vs undefined ?


{}


undefined





Be careful with __proto__.
– RobG
Aug 27 '14 at 2:37


__proto__




3 Answers
3



You are unable to redefine the property because Object.defineProperty() defaults to non-configurable properties, from the docs:


Object.defineProperty()



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.


configurable: true



Properties defined through Object.defineProperty() are, by default, non-configurable.


Object.defineProperty()


configurable



To allow them to be redefined, or reconfigured, they have to be defined with this attribute set to true.


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.


o.prototype


undefined


prototype



Such properties are found on constructor functions for new instances to inherit from, roughly equivalent to:


function


new


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:


[[Prototype]]


__proto__


console.log(o.__proto__); // {}



The standardized way to read the [[Prototype]] is with Object.getPrototypeOf():


[[Prototype]]


Object.getPrototypeOf()


console.log(Object.getPrototypeOf(o)); // {}





And ES6 may introduce Object.setPrototypeOf, overwhelmed by choice…
– RobG
Aug 27 '14 at 2:43




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.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Render GeoTiff to on browser with leaflet

How to get chrome logged in user's email id through website

using states in a react-navigation without redux