2

I'm building a system, with similar details as this question: Can I have different copies of a static variable for each different type of inheriting class

Except it's in JavaScript!

I'm going to have a set of subclasses. Each subclass will have a lot of instances created of it during the life of the program. Each instance of a particular subclass will have different values, except for a file that is common to all. I don't want each instance to have a copy. I want it static (one copy for all). Each different subclass uses a different file though. I want each subclass to inherit the FACT that it HAS a file from a superclass.

EDIT: Quick Summary:

goal: create a class that is a constructor that constructs the definition of a subclass, allowing a variable: - Appearing in every subclass - Unique to a particular subclass - Shared by all instances of a particular subclass (one copy for all)

Attempt at illustrating this in code:

var instance1ofSubclass1 = {
    staticVar:"SAMEVAL_1", // For brevity I'm showing how staticVar is  
                           // the same. It's notsupposed to be public.
    uniqueVar:"adsfasdf"
};
var instance2ofSubclass1 = {
    staticVar:"SAMEVAL_1",
    uniqueVar:"zxbvczbxc"
};
var instance3ofSubclass1 = {
    staticVar:"SAMEVAL_1",
    uniqueVar:"qwrtytry"
};

var instance1ofSubclass2 = {
    staticVar:"SAMEVAL_2", //<--notice the static var is different
                           //   between subclasses
    uniqueVar:"oipoiuu"
};
var instance2ofSubclass2 = {
    staticVar:"SAMEVAL_2",
    uniqueVar:"hljkhlj"
};
var instance3ofSubclass2 = {
    staticVar:"SAMEVAL_2",
    uniqueVar:"bnmbmbmnm"
};

My class definitions could go like this:

var subclass1 = (function () {
    var staticVar = "SAMEVAL_1"
    return function (unique) {
        return {
            uniqueVar:unique
        };
    };
}());

var subclass2 = (function () {
    var staticVar = "SAMEVAL_2" //<-- different static variable
    return function (unique) {
        return {
            uniqueVar:unique
        };
    };
}());

Now, I want to go a step further and make a superclass for these classes. That's where I'm stuck. I don't want to have a staticVar definition in every subclass. I want to get it from the superclass.

Community
  • 1
  • 1
JustcallmeDrago
  • 1,885
  • 1
  • 13
  • 23
  • 1
    I'm not entirely clear on what you are asking for. Can you clarify what you would like to write and why it doesn't meet your needs? – Phrogz Jan 19 '11 at 21:04
  • @Phrogz: I'll edit it. Should I completely edit it, or just append a big edit to the end? – JustcallmeDrago Jan 19 '11 at 21:17
  • @JustcallmeDrago I'd go for either a big appended edit, or even a rewrite for clarity. :) – Phrogz Jan 19 '11 at 21:29
  • @Phrogz: Edited! Hope it's clear(er) now. I edited out the parasitic inheritance thing, but I still think it might be in the right direction for a solution. – JustcallmeDrago Jan 19 '11 at 21:35
  • Could you please clarify (perhaps correct) one thing? In the first code section, for the various instances of `subclass2`, the value of `staticVar` is not the same for each instance of that class. Was this just a copy/paste error? – user113716 Jan 19 '11 at 21:57
  • @Patrick: Thanks, yeah, copy/paste error. it's fixed now. – JustcallmeDrago Jan 19 '11 at 22:01
  • @JustcallmeDrago: The *only* way in javascript of making a variable private is in a function body. Your example shows `staticVar:"SAMEVAL_2",` which suggests that it is public. Your code at the bottom creates a private shared variable, but you want it to come from a super class. If it is coming via inheritance, then it isn't private. You could create a "super" function where you pass `"SAMEVAL_1"` to it and it just sends it back, but what would be the point? I worked up an example where a private variable in the super is only available within the sub instances via a function. Would that work? – user113716 Jan 20 '11 at 00:15
  • @Phrogz, @Patrick: I think I got it. Check my answer! – JustcallmeDrago Jan 21 '11 at 07:04

3 Answers3

0

First of, the compiler will never be able to prevent you from forgetting something since there is no compiler. That's something we'll have to live without.

My suggestion for you would be to use prototyping for this. If the prototype of the superclass contains your variable, the same instance will be used for all the subclasses. And you wont have to repeat yourself in your subclass-files. Static and inherited, so to speak.

MySuperClass.prototype.myStaticVar = "giantFile";

The downside of this solution is that the variable won't really be private. On the other hand, do you really, really need it to be private?

The concept of privacy is a little funny anyhow. In C/C++ everything (private stuff too) can be accessed by pointer-magic. In C# you can use reflection to alter private variables. Nothing is ever really private. JavaScript is even funnier since the scripts in the browser can be altered by the end-user himself! In my opinion, hiding in plain sight is the way to go in this case. Name your variable appropriately (for example, add an underscore or two the beginning of it's name to signify "privacy").

Jakob
  • 24,154
  • 8
  • 46
  • 57
0

if i'm reading this right, I had a similar issue that you did. Check this SO question that i posted a few weeks ago.

to take that a step further, my .add() method checks to see if the passed in namespace has a supr object attached to it, if not, then it appends the base object called supr to that namespace so that it can have easy access to the root.

Community
  • 1
  • 1
hellatan
  • 3,517
  • 2
  • 29
  • 37
0

I think I've figured it out.

Fiddle: http://jsfiddle.net/zXMaM/

The pattern I've created sends a class definition through another function (essentially the super class) that creates an additional closure for the necessary private static variables and at the same time augments the object created by the class passed in to access the private static variables.

It's hard to explain as this is new to me too, but hopefully between the code and my comments it is followable.

The "superclass" method:

var superClass = function (yourPrivateStaticVar, classDef) {        
    var privateStatic = yourPrivateStaticVar;

    return function () { // return a new constructor (only invoked when a new 
                         // instance is created!)

        // run the constructor, grab the object it creates
        var newObj = classDef();

        // now, augment the object created (these vars/methods have no 
        // knowledge of the subclass!)

        //add private vars/methods to the object
        function getPrivStatic() {
            return privateStatic;
        }

       var example_inherited_private_var;

        //add public vars/methods to the object
        newObj.getPrSt_directly = function () {
            return privateStatic;
        }

        newObj.getPrSt_throughPrivateFunc = function () {
            return getPrivStatic();
        }

       newObj.example_inherited_public_var = "something";

        //return the augmented object (a new *instance* of the subclass)
        return newObj;
    };
};

Defining a "subclass":

//pass the definition of subclass1 through the superclass method and get it back
var subClass1 = superClass("yourChosenPrivateStaticValue", function () {
    //private variables/methods go here

    return { //this is the actual instance object
        //public variables/methods go here
    };
});

Again, the fiddle: http://jsfiddle.net/zXMaM/

JustcallmeDrago
  • 1,885
  • 1
  • 13
  • 23