Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function not listed under Object.keys or Object.getOwnPropertyNames but can be invoked

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 (...){...}
like image 583
Aman Gupta Avatar asked May 19 '16 09:05

Aman Gupta


2 Answers

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.

like image 105
Emil Ingerslev Avatar answered Sep 25 '22 02:09

Emil Ingerslev


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.

like image 39
Rudolf Gröhling Avatar answered Sep 27 '22 02:09

Rudolf Gröhling