Search code examples
javascriptobjecttypesdescriptor

Why does calling Object.getOwnPropertyDescriptors on a date object return an empty array?


I'm trying to understand how JavaScript objects work fully. I know that when you call Object.getOwnPropertyDescriptors on an object, you get an object containing the descriptors. For example, if you defined your own object, and got the descriptors, you would get something like this:

let foo = {
  bar: 2
}

Object.getOwnPropertyDescriptors(foo);
// Output: 
// {
//   bar: {
//     value: 2,
//     writable: true,
//     enumerable: true,
//     configurable: true,
//   }
// }

Likewise, if you get the descriptors on a built-in object, e.g. like an Error, you can see the descriptors of the error object.

let foo = new Error();

Object.getOwnPropertyDescriptors(foo);
// Output: 
// {
//   bar: {
//     value: 'Error\n    at <anonymous>:1:11',
//     writable: true,
//     enumerable: false,
//     configurable: true,
//   }
// }

I understand that the property was created when the Error constructor was called. Everything that I've just stated makes sense to me. However, when I try to get the descriptors of a date object, nothing is returned.

let foo = new Date();

Object.getOwnPropertyDescriptors(foo);
// Output: 
// {}

I can get the value of the date as a string just by accessing it, but why is there not a descriptor for the value?


Solution

  • Date objects are not said to contain any own-properties. Per the spec:

    21.4.5 Properties of Date Instances

    Date instances are ordinary objects that inherit properties from the Date prototype object. Date instances also have a [[DateValue]] internal slot. The [[DateValue]] internal slot is the time value represented by this Date.

    And that's it.

    All the information contained for a given Date is within that [[DateValue]] internal slot, which is not exposed directly via JavaScript - it's accessed and manipulated only through the methods on Date.prototype, the object that date instances inherit from.

    I can get the value of the date as a string just by accessing it

    This works because you'd be calling the toString method which exists on the prototype. For example:

    const proto = {
      toString() {
        return 'foo';
      }
    };
    const instance = Object.create(proto);
    console.log(instance.toString());
    console.log(Object.getOwnPropertyDescriptors(instance));

    The object can have toString called on it without having any properties directly on the instance.