0

The idea is to get the list of methods/properties of class. For example, I have this class:

// foo.js
class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    //,
    meh() {
        return 'bar';
    }
}
module.exports = FooController;

Now I want to retrieve the member of FooController. This should be done easily for javascript plain object, but not with class:

// index.js
var Foo = require('foo');
var foo = new Foo();

// inspect
console.log(foo); // expected: { bar, meh }, but got {}

// struggle with lodash
var _ = require('lodash');    
console.log(_.keys(foo)); // expected ['bar', 'meh'], but got []

Any idea? Thanks in advance for any help or suggestions.

Adiono
  • 1,034
  • 11
  • 19

3 Answers3

2

classes in ES6 are just sugar coding over defining methods on a function's prototype in ES5. So for your example:

class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    //,
    meh() {
        return 'bar';
    }
}
module.exports = FooController;

the ES5 equivalent is:

var FooController = (function() {
    function FooController() { } // This method will act as our constructor

    // All methods defined on the prototype are equivalent with the
    // so called class methods in ES6
    FooController.prototype.bar = *function(next) { yield next; return 'meh'; };

    FooController.prototype.meh = function() { return 'bar'; };

    return FooController;
})();

to access the "public" methods of off FooController you can either:

  1. Access the prototype explicitly like so: FooController.prototype

    console.log(FooController.prototype.meh()) // => 'bar'

  2. Access the prototype of the constructed object likes so:

    var foo = new FooController(); var proto = foo.__proto__; console.log(proto.meh()) // => 'bar'

When you construct foo calling the new keyword, amoung other, these few steps will occour:

  1. A new object will be created
  2. The prototype of that object will point to the prototype of FooController;

As long as you think of class methods as sugar coding over prototype methods it becomes much easier to gain power over the situation.

Hope this helps.

Andrei CACIO
  • 2,101
  • 15
  • 28
  • It is not working, it shows `[]` on both ways (see: https://jsfiddle.net/budiadiono/r2wdgkmk/1/). I think I'm going to use @Dmitri Pavlutin's answer. – Adiono Mar 15 '16 at 08:49
  • `meh` and `bar` are not enumerable properties. That's why `Object.keys()` is not working. – Dmitri Pavlutin Mar 15 '16 at 08:54
  • Yes, Dimitri is right. I will edit my answer. You can access the methods directly from the prototype, you cannot list them using the `keys()` method. – Andrei CACIO Mar 15 '16 at 08:58
  • Ah I see it now, good explanation! thanks Andrei! – Adiono Mar 16 '16 at 01:52
1

You should query the prototype object of the Foo() class instance:

// index.js
var Foo = require('foo');
var foo = new Foo();

var _ = require('lodash');    
console.log(Object.getOwnPropertyNames((Object.getPrototypeOf(foo)))); // shows ['bar', 'meh', 'constructor']
// or
console.log(Object.getOwnPropertyNames(foo.__proto__)); // shows ['bar', 'meh', 'constructor']

The proposed _.keys(foo) returns only the owned properties of the object (bar() and meh() are inherited), which actually is empty[].

To retrieve the methods you need:

  • To access the prototype object of the instance
  • Enumerate the properties of the prototype. Because the needed properties are not enumerable (Object.keys() or _.keys() won't work), it's necessary to use Object.getOwnPropertyNames().

See more about Object.getPrototypeOf() and Object.getOwnPropertyNames().
See this fiddle for a complete example.

Dmitri Pavlutin
  • 18,122
  • 8
  • 37
  • 41
0

Option 1: you can print the class constructor, wich gives the desired result:

class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    meh() {
        return 'bar';
    }
}


var foo = new FooController();

console.log(foo.constructor);

function class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    meh() {
        return 'bar';
    }
}

Option 2: you can just print the class object without binding it:

class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    meh() {
        return 'bar';
    }
}

console.log(FooController);

function class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    meh() {
        return 'bar';
    }
}
Randy
  • 9,419
  • 5
  • 39
  • 56