Q:

Do JavaScript property descriptors support custom attributes?

I would like to define a JavaScript property using a property descriptor that has custom attributes, in other words, attributes other than the standard value, writable, etc... 
In the example below I have defined a property with a property descriptor that has the custom attribute customAttr. The call to Object.defineProperty works fine but later when I try to loop over the attributes of the property descriptor, my custom attribute is not listed.
Is what I am trying to do possible?

const o = {}

Object.defineProperty(o, 'newDataProperty', {
  value: 101,
  writable: true,
  enumerable: true,
  configurable: true,
  customAttr: 1,
})

const desc = Object.getOwnPropertyDescriptor(o, 'newDataProperty')

// List the descriptor attributes.
for (const prop in desc) {
  console.log(`${prop}: ${desc[prop]}`)
}

// PROBLEM: `customAttr` is not listed

A:

No, it's not possible. This is what Object.defineProperty does:

...
 3. Let desc be the result of calling ToPropertyDescriptor with Attributes as the argument.
 4. Call the [[DefineOwnProperty]] internal method of O with arguments name, desc, and true.
 5. Return O.

And in short, ToPropertyDescriptor simply ignores anything that's not "enumerable", "writable", "configurable", "value", "get" or "set":

...
Let desc be the result of creating a new Property Descriptor that initially has no fields.
If the result of calling the [[HasProperty]] internal method of Obj with argument "enumerable" is true, then
  
...

(repeat step 3 for other valid descriptor properties)
 10. Return desc.

A:

Resurrecting an old post here, but I found the idea interesting. You can extract the fact that functions are objects in javascript, and use the get function as the attribute holder :
function setPropertyAttribute(obj, propertyName, attributeName, attributeValue) {
  var descriptor = getCustomPropertyDescriptor(obj, propertyName);

  descriptor.get.$custom[attributeName] = attributeValue;
}

function getPropertyAttributes(obj, propertyName) {
  var descriptor = getCustomPropertyDescriptor(obj, propertyName);

  return descriptor.get.$custom;
}

function getPropertyAttribute(obj, propertyName, attributeName) {
  return getPropertyAttributes(obj, propertyName)[attributeName];
}

function getCustomPropertyDescriptor(obj, prop) {
  var actualDescriptor = Object.getOwnPropertyDescriptor(obj, prop);
  if (actualDescriptor && actualDescriptor.get && actualDescriptor.get.$custom) {
    return actualDescriptor;
  }

  var value = obj[prop];
  var descriptor = {
    get: function() {
      return value;
    },
    set: function(newValue) {
      value = newValue;
    }
  }
  descriptor.get.$custom = {};

  Object.defineProperty(obj, prop, descriptor);
  return Object.getOwnPropertyDescriptor(obj, prop);
}

Then :
var obj = {
  text: 'value',
  number: 256
}

setPropertyAttribute(obj, 'text', 'myAttribute', 'myAttributeValue');

var attrValue = getPropertyAttribute(obj, 'text', 'myAttribute'); //'myAttributeValue'

fiddle here.

