How to distinguish between a getter and a setter and a plain property in JavaScript?
When you are stringify
ing, you will lose all the undefined
and the Function objects. Instead, you can check if the returned property descriptor object has a non-undefined get
or set
properties and decide like this
If the property descriptor has a
value
property, it is a normal data property.If the property descriptor has
get
andset
properties, and both have functions as values, then it is an accessor property.If the property descriptor has
get
's value as a function, then it is a getter property.Otherwise, a setter property.
Since value
is there, it is a normal data property:
descriptor.hasOwnProperty('value');
// true
Here, value
is not there, but get
property is a function. So a getter property:
descriptorGetter.hasOwnProperty('value');
// false
typeof descriptorGetter.get === 'function';
// true
typeof descriptorGetter.set === 'function';
// false
Here also, value
is not there, but set
property is a function. So a setter property:
descriptorSetter.hasOwnProperty('value');
// false
typeof descriptorSetter.get === 'function';
// false
typeof descriptorSetter.set === 'function';
// true
Apart from that, if you had an accessor property, like this
var o = {
get cabbage() {
return 'cabbage';
},
set cabbage(value) {
this._cabbage = value;
},
};
descriptorCabbage = Object.getOwnPropertyDescriptor(o, 'cabbage');
console.log(descriptorCabbage.hasOwnProperty('value'));
// false
console.log(typeof descriptorCabbage.get === 'function');
// true
console.log(typeof descriptorCabbage.set === 'function');
// true
You can write this as a function, like this
function getTypeOfProperty(object, property) {
var desc = Object.getOwnPropertyDescriptor(object, property);
if (desc.hasOwnProperty('value')) {
return 'data';
}
if (typeof desc.get === 'function' && typeof desc.set === 'function') {
return 'accessor';
}
return typeof desc.get === 'function' ? 'getter' : 'setter';
}
console.log(getTypeOfProperty(o, 'foo'));
// data
console.log(getTypeOfProperty(o, 'bar'));
// getter
console.log(getTypeOfProperty(o, 'bam'));
// setter
console.log(getTypeOfProperty(o, 'cabbage'));
// accessor