Дескрипторы свойств javascript поддерживают пользовательские атрибуты?
Я хотел бы определить свойство javascript, используя дескриптор свойства с пользовательскими атрибутами, другими словами, атрибуты, отличные от стандартных "значений", "записываемых" и т.д. ниже, например, я определил свойство с дескриптором свойств, который имеет пользовательский атрибут "customAttr". вызов Object.defineProperty отлично работает, но позже, когда я пытаюсь перебрать атрибуты дескриптора свойства, мой пользовательский атрибут не указан. Это то, что я пытаюсь сделать возможным? Спасибо вам
var o = {};
Object.defineProperty(o, "newDataProperty", {
value: 101,
writable: true,
enumerable: true,
configurable: true,
customAttr: 1
});
var desc2 = Object.getOwnPropertyDescriptor(o, "newDataProperty");
// List the descriptor attributes.
for (var prop in desc2) {
console.log(prop + ': ' + desc2[prop]);
}
//PROBLEM: "customAttr" is not listed
Ответы
Ответ 1
Нет, это невозможно. Это то, что Object.defineProperty
делает:
...
3. Пусть desc является результатом вызова ToPropertyDescriptor
с атрибутами в качестве аргумента.
4. Вызовите внутренний метод O [[DefineOwnProperty]] с аргументами name, desc и true.
5. Возврат O.
Иными словами, ToPropertyDescriptor
просто игнорирует все, что не "перечислимо", "записывается", "настраивается", "значение", "get" или "set":
(повторите шаг 3 для других допустимых свойств дескриптора)
10. Возвратите desc.
Ответ 2
Воскрешая старый пост здесь, но я нашел эту идею интересной. Вы можете извлечь тот факт, что функции являются объектами в javascript, и использовать функцию get
в качестве владельца атрибута:
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);
}
Тогда:
var obj = {
text: 'value',
number: 256
}
setPropertyAttribute(obj, 'text', 'myAttribute', 'myAttributeValue');
var attrValue = getPropertyAttribute(obj, 'text', 'myAttribute'); //'myAttributeValue'
скрипт здесь.