3

I'm currently diving into Spine and I'm currently asking myself what would be the most elegant way to define a private function, using Spine's class creation method.

var PrinterManager = Spine.Class.create({

    init: function () {

    },

    getAllAvailablePrinters: function () {

    },

    printDocument: function () {

    }

});

(function () {

    var instantiateActiveX = function(){
        console.log("...");
    }

    PrinterManager.include({
        pubInitActiveXPrinter: function(){
            instantiateActiveX();
        }
    });

})();

As you can see I want instantiateActiveX to be private and not visible to the outside. Using the JavaScript closure function trick, I can make it private without any problems, but this solution doesn't seem too elegant to me in the contest of creating classes like Spine does.

The code works, i.e. I can call PrinterManager.init().pubInitActiveXPrinter() which will then internally call the private function and - correctly - I cannot call PrinterManager.init().instantiateActiveX().

My Question - Is there a more elegant way to do it with Spine that I didn't yet discover??

Juri
  • 32,424
  • 20
  • 102
  • 136

2 Answers2

0

Well to put it simple, there's no way other than closures to make some function/variable invisible/private from the global scope.

WTK
  • 16,583
  • 6
  • 35
  • 45
  • Sure, you need closure in JavaScript to "emulate" private scope. That's clear and given. My objection was more regarding Spine, as the author seems to rely on a pure conventional mechanism, which might be fine, but isn't as "secure" as emulating private scope. While the above mechanism works perfectly as "instantiateActiveX()" isn't "public", it is quite cumbersome to integrate... – Juri Sep 13 '11 at 13:28
  • So we're clear that there's no way of declaring something as private other than using closure, and that is one-and-only answer for your question. Of course there are a dozen ways you can declare one function inside the other but its more matter of markup than actual change of functionality. What seems *elegant* to one, isn't necessarily elegant to someone else. – WTK Sep 13 '11 at 19:07
0

No.

"private" functions don't exist. You only have local functions and closure state. And using local functions/variables and closures for state does not mix well with using prototypical inheritance.

The real question you should be asking is "why do you need private functions" because you don't.

If a function is unstable and shouldn't be used because the API might change just prepend it with _

var PrinterManager = {
   ...
   _instantiateActiveX: function() { 
       ...
   }
}

If anyone uses these internal functions or variables then they have no right to complain when their code breaks if you change it.

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • 2
    Prepending functions with an underscore is just a convention and doesn't stop anyone from using it from global scope. The're cases where tottaly private functions make sense - there are reasons why there are private/protected modifiers in other languages. – WTK Sep 13 '11 at 09:39
  • @WTK Why? Why do you need private functions. – Raynos Sep 13 '11 at 09:45
  • To hide your code from the global scope and provide only public, *entry* points that modify state of your object. – WTK Sep 13 '11 at 09:52
  • @WTK "hide from global scope" Well it's already in an object so it's not in global scope. And prepending functions with `_` states that they are internal and will should be used at own risk. I don't see anything `private` adds apart from holding your hand and having the compiler slap you on the wrist if you do something bad – Raynos Sep 13 '11 at 09:54
  • Well private doesn't *add* anything apart from what already been said - it hides your functions or variables. It's encapsulation - a principal of object oriented programming - don't tell me you don't see the use for it... – WTK Sep 13 '11 at 10:00
  • @WTK I don't see the use for _forcing_ encapsulation at _compile time_. Methods give you encapsulation. – Raynos Sep 13 '11 at 10:11
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/3397/discussion-between-raynos-and-wtk) – Raynos Sep 13 '11 at 10:11