0

I'm working on a node module and i would like to keep using es6 classes syntax for style consistency but i found this pattern that I can't reproduce:

const proto = module.exports = function(options) {
    man.opts = options || {};
    function man(sentence) {
        man.say(sentence);
    }

    man.__proto__ = proto;
    man.age = 29;
    man.say = function(sentence) {
        console.log(sentence);
    };
    return man;
};

The strange thing of this function is that I can call it as a standard constructor and get a man with his methods and props but I can also call man as a function and get the same result as calling his method "say". Basically man('text') produces the same effect of man.say('text'); How can I recreate this pattern using es6 classes syntax?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Giovanni Bruno
  • 844
  • 2
  • 9
  • 13
  • function cane(sentence) actually is called man!!! – Giovanni Bruno Nov 10 '16 at 21:06
  • 3
    For the sake of maintainability, don't do that unless you have a very good reason to. – TimoStaudinger Nov 10 '16 at 21:07
  • @GiovanniBruno You can simple [edit] your questin to fix mistakes – Bergi Nov 10 '16 at 21:24
  • `man.__proto__ = proto;` is a really, really strange line. Why did you do this? – Bergi Nov 10 '16 at 21:26
  • I do not see a point in this, since depending on `__proto__ ` is already invalid es6 (and invalid/deprecated javascript in general). If you're trying to modernize/improve your code, converting it to a class is probably the last thing you'd want to do. – tcooc Nov 10 '16 at 21:29
  • @tcooc "invalid/deprecated" --- ? How so? – zerkms Nov 10 '16 at 21:35
  • @zerkms https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto It's not officially part of the language, and is deprecated according to standards. – tcooc Nov 10 '16 at 21:38
  • @tcooc I believe you better check the [*real standard*](http://www.ecma-international.org/ecma-262/7.0/#sec-object.prototype.__proto__) not MDN (which is simply a wiki, and contains heaps of mistakes). – zerkms Nov 10 '16 at 21:39
  • 2
    @zerkms It's [officially deprecated by that standard](http://stackoverflow.com/a/36061819/1048572). – Bergi Nov 10 '16 at 21:42
  • @Bergi oh wow :-S – zerkms Nov 10 '16 at 21:44
  • @Bergi Wow, I knew `__proto__` was deprecated, but totally missed the fact that the entire B section was "unofficial" features (since it listed features that I assumed to be standard due to being included in all? js engines). – tcooc Nov 10 '16 at 21:59
  • @tcooc There are "serverside" engines that don't implement them, for example Rhino. – Bergi Nov 10 '16 at 22:05
  • guys, just a hint of where i found this pattern: Express.js, the router class -_+ – Giovanni Bruno Nov 10 '16 at 22:36
  • @Bergi , tnx by the way for the "edit" tip, I didn't saw it ;) – Giovanni Bruno Nov 10 '16 at 22:45

1 Answers1

1

Basically man('text') produces the same effect of man.say('text')

Best don't use that pattern at all.

How can I recreate this pattern using es6 classes syntax?

You can do it similar to extending Function:

export default class {
    constructor(options) {
        const man = sentence => this.say(sentence);
        Object.setPrototypeOf(man, new.target.prototype);

        man.opts = options || {};
        man.age = 29;

        return man;
    }
    say(sentence) {
        console.log(sentence);
    }
}
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • understood, tnx! I'll try to refactor my branch of Express removing this terrible pattern but if things becomes too hard I will try this way – Giovanni Bruno Nov 10 '16 at 22:40