darksoulsong darksoulsong - 24 days ago 9
Javascript Question

Javascript - List all properties/methods from an object

I know that an object literal can have its keys listed by using

Object.keys()
method. But what about an object that was created through a constructor function?

function Foo () {}
Foo.prototype.bar = 'bar';
Foo.prototype.baz = 'baz';

var foo = new Foo();
console.log(Object.keys(foo).join(', ')); // returns ''
console.log(Object.getOwnPropertyNames(foo).join(', ')); // returns ''

Answer

Object.keys will only get own enumerable properties, and getOwnPropertyNames will only get own properties (even if not enumerable). Neither of them will give you the names of properties inherited from the prototype (or its prototype, or its, ...).

If you only care about enumerable properties, see trincot's answer.

If you want all of them,¹ even if they're not enumerable, you have to loop through the prototype chain:

function getAllPropertyNames(obj) {
  var result = [];
  while (obj && obj !== Object.prototype) {
    result.push.apply(result, Object.getOwnPropertyNames(obj));
    obj = Object.getPrototypeOf(obj);
  }
  return result;
}

function Foo () {}
Foo.prototype.bar = 'bar';
Foo.prototype.baz = 'baz';

var foo = new Foo();
console.log(getAllPropertyNames(foo));

In that example, I stopped when we reached Object.prototype, but of course you could keep going until you hit null instead:

function getAllPropertyNames(obj) {
  var result = [];
  while (obj) {
    result.push.apply(result, Object.getOwnPropertyNames(obj));
    obj = Object.getPrototypeOf(obj);
  }
  return result;
}

function Foo () {}
Foo.prototype.bar = 'bar';
Foo.prototype.baz = 'baz';

var foo = new Foo();
console.log(getAllPropertyNames(foo));


¹ "If you want all of them..." Note that in the above, we haven't tried to get properties that are named by Symbols instead of strings. If we did, we'd use getOwnPropertySymbols as well as getOwnPropertyNames.