1

I'm working with a pattern that looks like so (pseudo example):

var FOO = (function(foo) {

    var foo = foo || {},
    setThis = 'someValue';

    //--------------------------------------------------------------------------
    //
    // Public methods:
    //
    //--------------------------------------------------------------------------

    foo.init = function(bar) {

        this.blah = [];

        // Constructor stuff here...

    };

    foo.doSomething = function(bar) {

        if (bar) {

            this.doSomethingElse();

            // Stuff here...

        }

    };

    foo.doSomethingElse = function() {

        // Stuff here...

    };

    //--------------------------------------------------------------------------
    //
    // Private methods:
    //
    //--------------------------------------------------------------------------

    foo._imPrivate = function() {

        // ... stuff here ...

        this.blah = xyz; // References this.

    };

    foo._morePrivate = function(el) {

        // No reference to this.

    };

    foo._otherPrivate = function(el) {

        // No reference to this.

    };

    return foo; // Expose the methods.

}(FOO || {}));

Instanciated like so:

window.onload = function() { FOO.init(stuff); }

Three questions:

  1. If my "private" methods don't reference this, should I just make them "standard" functions (i.e. function _imPrivate() { ... }, for example)? Reason why I ask: I have a few methods that reference this, but I don't want to give them public access; I also have a few "utility" methods that don't reference this... Can the methods that reference this be standard functions (in context of the module pattern)?
  2. Could someone provide an example of how I would implement a setter for the setThis variable?
  3. Do you see any room for improvements in the above code?
mhulse
  • 4,062
  • 6
  • 28
  • 35
  • You can pass the context for any function by using `.call` or `.apply`. So item #1 is not entirely true – zerkms Jul 23 '12 at 22:25
  • Your private methods are quite public. – Bergi Jul 23 '12 at 22:26
  • @zerkms Ah, right! I can't believe I did not think of that! Thank you! Cool! :) – mhulse Jul 23 '12 at 22:30
  • @Bergi Fixed the `mq` thing. Thanks! Also, I agree about the private being public... My goal is to make my private methods truly private, that's why I'm asking for help here. :D – mhulse Jul 23 '12 at 22:31

2 Answers2

3

The "private" methods aren't private at all, they're public. The OP doesn't seem to take any advantage of closures available from the use of an immediately invoked function expression (IIFE).

The value of a function's this is set by how you call a function, it isn't static (unless you use ES5 bind). It has nothing to do with "context" (at least not in the way context is used in ECMA-262, which is how the word should be used in the context of javascript).

Douglas Crockford's Private Members in JavaScript will help.

If you post a real example of what you are trying to do, you will likely get more help on how to exploit the module pattern in its implementation.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • Thank you RobG! I really appreciate the help. I am researching the keywords and links you mentioned. Sorry about the pseudo code example. I'm actually in the process of forking and modifying a GitHub repo... I'll post a link to the code and working example as soon as I get my latest changes checked in... I'll be back! :) – mhulse Jul 24 '12 at 00:20
  • Here's the [original code](https://github.com/JoshBarr/js-media-queries/blob/master/js/onmediaquery.js). I'm working on a fork, but it's not really ready to share yet... Hopefully that helps explain things better? – mhulse Jul 24 '12 at 22:24
  • Btw, thanks for the tip on IIFE keyword... That term is new to me. [Reading about it now](http://benalman.com/news/2010/11/immediately-invoked-function-expression/), interesting stuff! I'll try to figure out how to take advantage of an IIFE (it's not obvious to me as of yet). – mhulse Jul 24 '12 at 22:29
  • Cool. Once you get started on IIFEs they are a great way to create "singletons" that use closures rather than properties inherited from a `[[Prototype]]`. Closures are a very powerful feature of javascript. – RobG Jul 25 '12 at 02:40
2

1.

You can do _imPrivate.call(this, arg1, arg2,...);

And in this case this in the _imPrivate function will refer to the particular instance.

2.

var setThis = 'someValue';

foo.setter = function(value) {
    setThis = value;
};
zerkms
  • 249,484
  • 69
  • 436
  • 539
  • Awesome!!!! You rock! Thank you!!!! Not to sound like a total noob, but how would I call the setter before I instanciate? Upon instanciation, would the setter apply to that instance, or all created instances? Thank you!!!! – mhulse Jul 23 '12 at 22:32
  • @Micky Hulse: all your code is "static". So every variable and method there belong to a "class", not to an instance – zerkms Jul 23 '12 at 22:44
  • Thank you zerkms! I might have asked the wrong question: Here's a [quick demo page](http://jsbin.com/oqojuy) (see console) and here's [the code](http://jsbin.com/oqojuy/edit)... **I now see that the setter applies to both "instances"** (do I have to use `New` keyword?). Is there a way to create new instances that are independent of one another? Am I using the right pattern for this? At this point I think I need to do more research (rather than bug ya'll), so I appreciate any tips you throw my way now that my primary questions have been answered. :) – mhulse Jul 24 '12 at 00:17
  • @Micky Hulse: it is amazing answer about what's confusing you now http://stackoverflow.com/questions/1595611/how-to-properly-create-a-custom-object-in-javascript#1598077 – zerkms Jul 24 '12 at 00:23