3

Updated: This is an update to my previous question that was somewhat off topic as to what this StackExchange is aiming for. But I have a follow up question to the previous inquiry about this subject.

Object Model:

 var Soldier;

 Soldier = (function() {

    "use strict";

    function Soldier() {
        var privateVar = "privateValue";

        this.methodToGetPrivateValue = function() {
            return privateVar;
        }
    }

    var sharedPrivateVar = "sharedPrivateValue";

    function sharedPrivateMethod() {
        // I want to get value `privateVar`
    }

    Soldier.prototype = {
        publicVar: "publicValue",

        publicMethod: function() {
            return this.publicVar;
        },

        sharedPrivate: function() {
            return sharedPrivateVar;
        }
    }

    return Soldier;

 })();

 var marine = new Soldier();

So my updated question to make this topic more a proper question is if there is anyway to get a sharedPrivateMethod defined in this way to be able to access the private variable in the above setup?

The reason I am asking is that the sharedPrivateMethod is totaly invisible to the instanced object. While the function defined inside Soldier() is accessible to the instance because of the this.method = function(). I dont know if it has any real use at the moment but would be interesting to see if it was possible somehow.

9
  • 1
    Belongs on codereview.stackexchange.com Commented Nov 23, 2012 at 10:45
  • This is the typical way to do OOP in javascript. Note that your private variables are private static. Commented Nov 23, 2012 at 10:46
  • I was wondering if there was something like that, sorry for my ignorance. Feel free to remove this, I will move it over to codereview. @JanDvorak im guessing that is what creates a memory hog if an object is duplicated too much. Commented Nov 23, 2012 at 10:47
  • @SnapGravy The self-invoking function creating the Test function will only execute once, so your "private" variables are shared between all instances of new Test(). This will not waste memory. Commented Nov 23, 2012 at 10:51
  • @JanDvorak That is pretty cool, that was my primary concern. Thanks, safe to say this is a very viable way to operate in JavaScript then. Commented Nov 23, 2012 at 10:55

1 Answer 1

2

The problem with what you have there is that your _self variable is shared by all instances constructed via new Test, and so for instance, assume your privateMethod used it:

function privateMethod() {
    console.log(_self.message);
}

Then this:

var t1 = new Test();
t1.message = "Message 1";
var t2 = new Test();
t2.message = "Message 2";

t1.privateMethod();

...would log "Message 2", not "Message 1" as you would expect, because the second call to new Test has overwritten the _self_ variable.

Other than the _self variable, what you have is fine. It lets you have private data and functions shared by all instances, which is very handy. If you need to have truly private data that's specific to each instance, you need to create the function that uses that data in the constructor function itself:

function Test() {
    var trulyPrivate = 42;

    this.showTrulyPrivate = function() {
        console.log("trulyPrivate = " + trulyPrivate);
    };
}

Then trulyPrivate is genuinely private to the instance. The cost is the cost of creating a showTrulyPrivate function for each instance. (The function objects may be able to share the underlying code, a good engine will do that, but there will be separate function objects.)

So to wrap up:

var Test = (function() {
    // Data and functions defined here are private to this code
    // and shared across all instances. There is only one copy
    // of these variables and functions.
    var privateDataSharedByAll;

    function privateFunctionSharedByAll() {
    }

    function Test() {
        // Data and functions here are created for *each* instance
        // and are private to the instance.
        var trulyPrivate;

        this.hasAccessToTrulyPrivate = function() {
            // Has access to the shared private data *and* the
            // per-instance private data.
        };
    }

    return Test;
})();
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that is definitely a good answer to my question along with Jan's comments. Thanks for you answer!
@SnapGravy: No worries, glad that helped! If you're into JavaScript OOP, you might find my Lineage toolkit helpful.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.