我正在研究一些反射代码,试图去除属性和功能,但我似乎根本无法获得getter / setter。
我对属性的反射代码是:
Reflector = function() { };
Reflector.getProperties = function(obj) {
var properties = [];
var proto = obj;
while (proto != Object.prototype) {
console.log('Scrapping proto: ', proto);
for (var prop in proto) {
console.log('typeof ' + prop + ": ", typeof obj[prop]);
if (typeof obj[prop] != 'function') {
properties.push(prop);
}
}
proto = Object.getPrototypeOf(proto);
}
return properties;
};
它运行的示例(带有我的调试消息)是:
var SimpleTestObject = function() {
this.value = "Test1";
this._hiddenVal = "Test2";
this._readOnlyVal = "Test3";
this._rwVal = "Test4";
};
SimpleTestObject.prototype = {
get readOnlyVal() {
return this._readOnlyVal;
},
get rwVal() {
return this._rwVal;
},
set rwVal(value) {
this._rwVal = value;
},
func1: function() {
// Test
}
};
SimpleTestObject.func2 = function(test) { /* Test */ };
SimpleTestObject.outsideVal = "Test5";
var props = Reflector.getProperties(SimpleTestObject);
console.log('props: ', props);
console.log('Object.getOwnPropertyNames: ', Object.getOwnPropertyNames(SimpleTestObject));
console.log('rwVal property descriptor: ', Object.getOwnPropertyDescriptor(SimpleTestObject, 'rwVal'));
console.log('rwVal (2) property descriptor: ', Object.getOwnPropertyDescriptor(Object.getPrototypeOf(SimpleTestObject), 'rwVal'));
我希望看到输出到Reflection.getProperties(SimpleTestObject)
的{{1}}是['readOnlyVal', 'rwVal', 'outsideVal']
,但我只看到outsideVal
。此外,当我尝试使用getOwnPropertyDescriptor()
来查看rwVal
是否可枚举时,它会以未定义的形式返回。所以,想想也许它以某种方式显示在上面的原型中,我尝试上升到一个级别仍然未定义。
答案 0 :(得分:0)
对于枚举getter,请在原型上使用Object.keys或Object.getOwnPropertiesNames而不是构造函数或/和实例:
function readGetters(obj) {
var result = [];
Object.keys(obj).forEach((property) => {
var descriptor = Object.getOwnPropertyDescriptor(obj, property);
if (typeof descriptor.get === 'function') {
result.push(property);
}
});
return result;
}
var SimpleTestObject = function() {
this.value = "Test1";
this._hiddenVal = "Test2";
this._readOnlyVal = "Test3";
this._rwVal = "Test4";
};
SimpleTestObject.prototype = {
get readOnlyVal() {
return this._readOnlyVal;
},
get rwVal() {
return this._rwVal;
},
set rwVal(value) {
this._rwVal = value;
},
func1: function() {
}
};
SimpleTestObject.func2 = function(test) { /* Test */ };
SimpleTestObject.outsideVal = "Test5";
// For constructor
console.log(readGetters(SimpleTestObject.prototype));
// For instance
var instance = new SimpleTestObject();
console.log(readGetters(Object.getPrototypeOf(instance)));

答案 1 :(得分:0)
如果将Object.defineProperty
或Object.defineProperties
的getter和setter一起使用,则可以通过Object.getOwnPropertyNames
枚举setter / getter属性。
const _name = Symbol();
const _age = Symbol();
class Dog {
constructor(name, age) {
Object.defineProperties(this, {
name: {
// you can set enumerable true explicitly if you want
//enumerable:true ,
set(value) {
this[_name] = name;
},
get() {
return this[_name];
}
},
age: {
set(value) {
this[_age] = age;
},
get() {
return this[_age];
}
},
book: {
get() {
return "Book"
}
}
});
this.name = name;
this.age = age;
}
}
const dog = new Dog("spike", 3);
console.log(Object.getOwnPropertyNames(dog));