最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Do JavaScript property descriptors support custom attributes? - Stack Overflow

programmeradmin2浏览0评论

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

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

Share Improve this question edited Nov 27, 2019 at 7:57 Bill Tür stands with Ukraine 3,51530 gold badges40 silver badges51 bronze badges asked Feb 28, 2013 at 13:52 user2073948user2073948 1456 bronze badges 2
  • Out of interest, why do you want to do this? – James Allardice Commented Feb 28, 2013 at 14:08
  • hi james... please see the ment i entered below under your answer... at run time i would like to loop over all of the object's properties, check to see which ones are "decorated" with certain attributes, and based on the existence, absence, and values of those attributes, then proceed to do "things" like validation of the property... thanks again for the answer – user2073948 Commented Feb 28, 2013 at 14:20
Add a ment  | 

2 Answers 2

Reset to default 8

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":

  1. ...

  2. Let desc be the result of creating a new Property Descriptor that initially has no fields.

  3. 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.

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.

发布评论

评论列表(0)

  1. 暂无评论