当你使用`stringify`方法进行序列化时,所有的`undefined`和函数对象都将丢失。相反,你可以检查返回的属性描述符对象是否具有非undefined的`get`或`set`属性,并像这样做出决定:
1. 如果属性描述符具有`value`属性,则它是普通数据属性。
2. 如果属性描述符具有`get`和`set`属性,并且两者都具有函数值,则它是访问器属性。
3. 如果属性描述符具有`get`的值为函数,则它是getter属性。
4. 否则,是setter属性。
因为有`value`属性,所以它是一个普通数据属性。
descriptor.hasOwnProperty('value');
// true
这里,“value”不存在,但“get”属性是一个函数。所以它是一个getter属性:
descriptorGetter.hasOwnProperty('value');
typeof descriptorGetter.get === 'function';
typeof descriptorGetter.set === 'function';
同样,在这里,value
不存在,但 set
属性是一个函数。因此,set
属性是一个 setter 函数:
descriptorSetter.hasOwnProperty('value');
typeof descriptorSetter.get === 'function';
typeof descriptorSetter.set === 'function';
此外,如果您有一个访问器属性,像这样
var o = {
get cabbage() {
return 'cabbage';
},
set cabbage(value) {
this._cabbage = value;
},
};
descriptorCabbage = Object.getOwnPropertyDescriptor(o, 'cabbage');
console.log(descriptorCabbage.hasOwnProperty('value'));
console.log(typeof descriptorCabbage.get === 'function');
console.log(typeof descriptorCabbage.set === 'function');
你可以写一个函数,像这样:
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'));
console.log(getTypeOfProperty(o, 'bar'));
console.log(getTypeOfProperty(o, 'bam'));
console.log(getTypeOfProperty(o, 'cabbage'));
!({a:1}).__lookupGetter__("a")
会返回 false,因为a
不是 getter。如果它是 getter,那么函数将强制转换为 true,所以最终结果类似于 hasOwnProperty(),但是针对 getter... - dandavis