0

Possible Duplicate:
Crockford’s Prototypal inheritance - Issues with nested objects

I'm having a problem getting the following code to execute a function in prototype B from prototype A, and was wondering if there was any easy solution:

var Ob = function () {
  test = 'hi';
}

Ob.prototype.A = {
  that : this,
  root : this,
  goB : function () {
    var that = this;

    console.log('hello');
    that.B.wtf();
  }
}

Ob.prototype.B = {
  that : this,
  root : this,
  wtf : function () {
    var that = this;

    console.log(that);
  }
}

test = new Ob;
test.A.goB();
Community
  • 1
  • 1
PlugTrade
  • 837
  • 11
  • 19
  • `that = this` does not reference your `Ob` instance, but just the object you put in a property on `Ob.prototype`! – Bergi Nov 07 '12 at 13:57
  • related: [Inheritance issues with nested objects](http://stackoverflow.com/questions/10131052/crockfords-prototypal-inheritance-issues-with-nested-objects) – Bergi Nov 07 '12 at 13:59

2 Answers2

2

When you assign object literals A and B to the prototype of Ob, you are putting two object literals with some methods on the prototype. You are NOT putting the methods on the prototype. Thus when you execute that methods on those object literals in the context of the instance test, this doesn't mean what you think it means.

hvgotcodes
  • 118,147
  • 33
  • 203
  • 236
1

You need to wire up your properties after the object has been created:

var Ob = function () {
    var that = this;

    // set the current root to this instance and return the object
    this.getA = function() {
        that.A.currentRoot = that;
        return that.A;
    };

    this.getB = function() {
        that.B.currentRoot = that;
        return that.B;
    };
};

Ob.prototype.A = {
    goB : function () {
        var that = this.currentRoot;

        console.log('hello');
        that.getB().wtf();
    }
};

Ob.prototype.B = {
    wtf : function () {
        var that = this.currentRoot;

        console.log(that, this);
    }
};


test = new Ob;
test.getA().goB();

A rather dirty hack is to use a privileged method in the parent object to augment the child object and return it so you have access to the parent object via a property. The dirty part is that if you cache the object the property is not guaranteed to have the correct value. So this is more or less a way to do it although you really shouldn't do it this way.

Torsten Walter
  • 5,614
  • 23
  • 26
  • `A.root = B.root = this;` There's no `A` or `B` variable in the constructor. And if you mean `this.A.root = this.B.root = this;`, you will be overwriting the value every time the constructor is called. – I Hate Lazy Nov 07 '12 at 14:00
  • Good point. I should have checked again before I reformatted the answer. I'll update the answer. – Torsten Walter Nov 07 '12 at 17:46
  • exactly what I was looking for. Thanks Torsten. – PlugTrade Nov 11 '12 at 17:32