5
\$\begingroup\$

I have either created something beautiful or something monstrous, and I'm not really sure which, and I don't know where else to turn but here. What I've done:

var MyObject = function(opts) { 
    //init code, set vals, runs when 'new MyObject()' is called
}

MyObject.prototype = (function() {
    //private helper functions
    //scoping is a pain, but doable
    function myPrivateFunction() {}

    return {
        publicFunc1: function() { /* uses myPrivateFunction() */ }
        , publicFunc2: function() { /* uses myPrivateFunction() */ }
    };
})();

MyObject.prototype.publicFunc3 = function() {}
MyObject.prototype.publicFunc4 = function() {}
MyObject.prototype.publicFuncEtc = function() {}

To my surprise, this works, and takes care of a pretty significant problem of creating reusable private functions for various public functions. Of course, I have to do some scoping for the this object, but I feel it's a small price to pay for being able to use private reusable functions. I left the other functions on the outside to avoid having to deal with scoping.

My question is: is this a code smell? and as a corollary, is there a better way to do this?

\$\endgroup\$
4
  • 1
    \$\begingroup\$ publicFunc3 can't see myPrivateFunction... sort of smells. And of course privates don't have a this, which sort of defeats OO design. Why not just wrap the whole thing in a IIFE and put the private stuff inside? \$\endgroup\$
    – Dagg
    Apr 24 '13 at 22:37
  • \$\begingroup\$ yes.. that's because it doesn't need to. is that bad? \$\endgroup\$
    – Jason
    Apr 24 '13 at 22:39
  • \$\begingroup\$ It's probably not good... someone else working with the code will probably assume all public "methods" have access to all "private" ones. Personally, I think not worrying about trying to make things private makes life a lot easier when dealing with languages with no concept of private ;) \$\endgroup\$
    – Dagg
    Apr 24 '13 at 22:40
  • \$\begingroup\$ that's a fair point. \$\endgroup\$
    – Jason
    Apr 24 '13 at 22:41
3
\$\begingroup\$

The commenters pretty much said it all:

  • publicFunc3 can't see myPrivateFunction <- not good
  • I would declare function() { /* uses myPrivateFunction() */ } as a private function and then just return a pointer to it:

    MyObject.prototype = (function() {
        //private helper functions
        //scoping is a pain, but doable
        function myPrivateFunction() {}
        function myPrivateFunction2() {/* uses myPrivateFunction() */ }
        function myPrivateFunction3() {/* uses myPrivateFunction() */ }
    
        return {
            publicFunc1: myPrivateFunction2
          , publicFunc2: myPrivateFunction3
        };
    })();
    
  • I know there is a "comma first" movement out there, but it looks silly to me

Other than that, this code does not look monstrous to me, if it works for you, then why not.

\$\endgroup\$
1
  • \$\begingroup\$ you should try going comma-first for a bit ;) \$\endgroup\$
    – Jason
    Mar 21 '14 at 17:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.