2

Given the following code is it posible to access an object's property from inside a "sub" object?

I imagine I'm doing this completely wrong, but I'm not sure what the right pattern to do is here. Any help would be much appreciated.

function MainObject(){
    this.someProperty = "asdf";
    return this;
}

MainObject.prototype.subClass = {};
MainObject.prototype.subClass.sayHi = function(){
    // 'this' refers to the instance of MainObject.subClass
    // How do I get to the instance's MainObject.someProperty property from here,
    // without calling "widget.someProperty"?
};

widget = new MainObject();
ianneub
  • 357
  • 2
  • 8
  • 2
    *"I imagine I'm doing this completely wrong..."* Perhaps, what are you trying to achieve? Some kind of "inner class"-like thing? If you're trying to do inheritance (rather than "inner" stuff), [this other answer](http://stackoverflow.com/a/11072626/157247) here on SO has a full example with explanation. – T.J. Crowder Jul 12 '12 at 15:29
  • I want MainObject to comprise a single point from which a user can access my whole JS library. So after the line: `widget = new MainObject();` a user would only need to call `widget` to interact with my library. Internally my library would do many different things, but should never need to know that `widget` was the variable the user chose to use. – ianneub Jul 12 '12 at 15:41

2 Answers2

3

You can't since there is no reference to the actual instance. You'd have to initialize subClass for each instance inside the constructor:

function MainObject(){
    var self = this;
    this.someProperty = "asdf";
    this.subClass = {};
    this.subClass.sayHi = function(){
        //self.someProperty
    }
};

But that replicates functionality. It seems you should choose an other approach altogether.

Maybe using composition would be better, but that really depends on what you are trying to do and how the "classes" relate to each other.

function SubClass(instance) {
    this.instance = instance;
}

SubClass.prototype.sayHi = ...;

function MainObject(){
    this.someProperty = "asdf";
    this.subClass = new SubClass(this);
}
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • I used a poor choice calling it "subClass" when really its just going to be a separate class altogether, I just want it to be accessible from a single instance point. `widget` should be the only variable that a user needs to instantiate to use my library. I don't think this pattern would work in that case is that correct? – ianneub Jul 12 '12 at 15:56
  • 1
    @ianneub: I that case I think you are looking for some module pattern. Example: http://stackoverflow.com/questions/5647258/how-to-use-revealing-module-pattern-in-javascript – Felix Kling Jul 12 '12 at 16:21
  • I went ahead and marked your answer as the solution. I ended up changing the way I handle the API and instead of allowing the user to instantiate the object for them, I do it in my code and present them with that object. More similar to how jQuery does it. Thanks also to T.J. Crowder, those were very valuable links. – ianneub Jul 13 '12 at 19:18
2

There's no reference to the actual parent, so you'll have to store one manually in the subclass. Here's an example:

function MainObject() {
    // your code

    this.subClass = {
        parent: this
    }
}
Elliot Bonneville
  • 51,872
  • 23
  • 96
  • 123