5

Suppose there is some library javascript object jsObj. On calling Object.keys or Object.getOwnPropertyNames , I get a list of properties like

[a,b,c,d]

But still I can call a function like jsObj.e(). Why the the method e is not part of Object.keys or Object.getOwnPropertyNames? How they are doing it?

Here, it says that Object.getOwnPropertyNames will return non enumerable properties too. So what is the characterstic of property like e above.

I am using opentok server side SDK. Using following code,

var OpenTok = require('opentok');
var opentok = new OpenTok(config.tokbox.apiKey, config.tokbox.secret);
console.log("opentok1", Object.getOwnPropertyNames(opentok));
prints -> // [ '_client',
  'apiKey',
  'apiSecret',
  'apiUrl',
  'startArchive',
  'stopArchive',
  'getArchive',
  'deleteArchive',
  'listArchives' ] 
console.log("opentok2", opentok.createSession);
prints -> function (...){...}
Community
  • 1
  • 1
Aman Gupta
  • 3,627
  • 4
  • 40
  • 64
  • Do share executable demo.. Unable to understand the issue.... – Rayon May 19 '16 at 10:13
  • 3
    It's probably inherited from one of its prototypes? If you do this: `for(prop in obj) { console.log(prop); }` (where obj is your object), does it get outputted then? – Arg0n May 19 '16 at 10:15
  • Added some code, not executable because you need your own api keys. Hopefully, that will explain the question clearly – Aman Gupta May 19 '16 at 10:30

2 Answers2

6

Object.e must be defined on the object's prototype. Like this:

var test = function() {}
test.prototype = { e: function() { return 'e'; } }
var obj = new test();
Object.keys(obj) // returns []
obj.e() // returns 'e'

A way of getting the prototypes keys is simply getting the prototype and the use the Object.keys() function:

Object.keys(Object.getPrototypeOf(obj))

This will however not give you keys of the prototypes prototype.

Emil Ingerslev
  • 4,645
  • 2
  • 24
  • 18
3

The propety of an JS Object could be

  • own -- means it is defined on the object directly
  • inherited -- the property is callable, but is defined in prototype (the Object predecessor)
  • enumerable / not enumerable -- some properties (like length) are not enumerable, you can define your own non enumerable property with Object.defineProperty()

then iterating functions works on some subset of this properties:

  • Object.keys() -- returns an array of a given object's own enumerable properties.
  • Object.getOwnPropertyNames -- returns an array of all properties (enumerable or not) found directly upon a given object

so none of this function iterates over inherited properties. If you wanna iterate all properties without resolution of ownership, then you need for... in cycle, like:

var keys = [];
for (var key in object)
    keys.push(key);

but this will not iterate over non-enumerable properties.

For complete overview of ownership and enumerability see this documentation.

Rudolf Gröhling
  • 4,611
  • 4
  • 27
  • 37