Pesquisa de site

javascript - Obter as propriedades públicas de uma classe sem criar uma instância dela?


Vamos imaginar que temos uma classe JavaScript:

var Person = (function () {
    function Person(name, surname) {
        this.name = name;
        this.surname = surname;
    }
    Person.prototype.saySomething = function (something) {
        return this.name + " " + this.surname + " says: " + something;
    };
    return Person;
})();

Quero iterar seus métodos e propriedades. Não tenho problemas com os métodos.

  var proto = Person.prototype,
      methods = Object.keys(proto);

  // iterate class methods ["saySomething"]
  for (var i = 0; i < methods.length; i++) {
    // do something...
  }

Meu problema surge quando quero iterar sobre suas propriedades:

  var proto = Person.prototype,
      targetInstance = new Person(), // this is my problem!
      properties = Object.getOwnPropertyNames(targetInstance),

  // iterate class properties ["name", "surname"]
  for (var i = 0; i < properties.length; i++) {
    // do something...
  }

A única maneira que encontrei é criar uma instância e usar Object.getOwnPropertyNames. Quero usar este código como parte de um framework, então não terei controle sobre as classes definidas por outros desenvolvedores. Quero evitar a necessidade de criar uma instância porque, se o construtor tivesse algum tipo de validação como:

function Person(name, surname) {

  if(typeof name === "undefined" || typeof surname === "undefined"){ 
    throw new Error() 
  }

  this.name = name;
  this.surname = surname;
}

Eu não seria capaz de usar o código acima. Você sabe se é possível obter as propriedades públicas de uma classe sem criar uma instância dela?

Resposta #1

As propriedades não existem até que um objeto as construa. Se sua classe fosse assim:

var Person = (function () {
    Person.prototype.name = null;    
    Person.prototype.surname = null;
    function Person(name, surname) {
        this.name = name;
        this.surname = surname;
    }
    Person.prototype.saySomething = function (something) {
        return this.name + " " + this.surname + " says: " + something;
    };
    return Person;
})();

você também veria nome e sobrenome, mas é claro que você não pode contar com os objetos parecendo assim.

Resposta #2

Você sabe se é possível obter as propriedades públicas de uma classe sem criar uma instância dela?

Se você está falando sobre runtime deles, não, não sem hacks feios como toString (que te dá uma representação string do corpo da função).

No entanto, você pode obter isso em tempo de compilação usando o serviço de linguagem TypeScript e, em seguida, fazer geração de código para auxiliar em tempo de execução (https://github.com/Microsoft/TypeScript/wiki/Using-the-Language-Service-API).

Nenhum desses é trivial.

Artigos relacionados