JavaScript Constructors

Dear Campers:
I have been going through the Understanding JavaScript Constructors tutorial at CSS-Tricks, however there’s this hairy method called the:

Object.defineProperty()

Method which according to them can be used inside a constructor to help perform all necessary property setup.
I have completely failed to make sense of what it exactly does whenever defining a constructor. Can someone help me understand or point me to online resources for further insights about

Object.defineProperty()

It’s a way to manipulate aspects of the object. You are calling the Object constructor and telling it you want to manipulate an object. Manipulating values of the object are easy, but manipulating some underlying attributes, if it is enumerable, writable, etc. - that take a bit more work:

const myObj = { prop1: 1 };
console.log(myObj);
// {prop1: 1}
for (let prop in myObj) {
  console.log(prop, '-', myObj[prop]);
}
// prop1 - 1

myObj.prop2 = 2;
console.log(myObj);
// {prop1: 1}
for (let prop in myObj) {
  console.log(prop, '-', myObj[prop]);
}
// prop1 - 1
// prop2 - 2

Object.defineProperty(myObj, 'prop3', { value: 3 }); // enumerable defaults to false
console.log(myObj);
// {prop1: 1, prop2: 2, prop3: 3}
for (let prop in myObj) {
  console.log(prop, '-', myObj[prop]);
}
// prop1 - 1
// prop2 - 2

Object.defineProperty(myObj, 'prop4', { value: 4, enumerable: true });
console.log(myObj);
// {prop1: 1, prop2: 2, prop4: 4, prop3: 3} // reminder: order is not guaranteed in objects
for (let prop in myObj) {
  console.log(prop, '-', myObj[prop]);
}
// prop1 - 1
// prop2 - 2
// prop4 - 4

Object.defineProperty(myObj, 'prop5', { value: 5, writable: true });
console.log(myObj);
myObj.prop1 = 'one'; // no problem, writable for that defaulted to true
myObj.prop3 = 'three'; // because of how this was created with Object, writeable defaulted to false, doesn't change, throws an error in strict mode
myObj.prop5 = 'five'; // no problem, because I said it was writable
console.log(myObj);
// {prop1: "one", prop2: 2, prop4: 4, prop3: 3,  prop5: "five"}

MDN is a good resource. Here is its explanation.

Do you need to be able to do this? I don’t know, I’ve never actually used it. But maybe sometime in the future I will and it’s good to know that it is there. There are other ways to manipulate these attributes, but this is one.

1 Like

One way it’s often used is if you were extending a built-in JS constructor - e.g. if you were adding a method foo to Array, often you would use:

Object.defineProperty(Array.prototype, 'foo', {
  value: function() {
    return "foo bar baz";
  }, 
  writable: false,
  configurable: false,
  enumerable: false
});