无法枚举getter / setter属性

时间:2015-04-21 12:36:07

标签: javascript reflection

我正在研究一些反射代码,试图去除属性和功能,但我似乎根本无法获得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是否可枚举时,它会以未定义的形式返回。所以,想想也许它以某种方式显示在上面的原型中,我尝试上升到一个级别仍然未定义。

2 个答案:

答案 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.definePropertyObject.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));