Mariya Davydova
Mariya Davydova

Reputation: 1393

CoffeeScript: Accessing outer class objects from inner class instance

If there any way to access outer class fields from inner class instance, EXCEPT passing outer class instance to inner class constructor?

To be more specific, I have a simple example:

class Test
  constructor: (@number) ->

  class SubTest
    constructor: (@name) ->

    toString: () ->
      console.log @name, @number

  getSubTest: () ->
    return new SubTest "SubTest"

test = new Test 10
test.getSubTest().toString() # SubTest undefined

So, I want to get "SubTest 10" instead of "SubTest undefined". Is it possible?

Upvotes: 10

Views: 3170

Answers (2)

pghalliday
pghalliday

Reputation: 331

It's an old question but the accepted answer doesn't work if multiple instances of the outer class are needed (as pointed out by @costa-shapiro). Here is an alternative approach to create the closure with the inner class.

SubTest = (test) ->
  class SubTest
    constructor: (@name) ->

    toString: () =>
      console.log @name, test.number

class Test
  constructor: (@number) ->
    @SubTest = SubTest @

  getSubTest: () =>
    return new @SubTest "SubTest"

test = new Test 10
test.getSubTest().toString()

Upvotes: 1

asawyer
asawyer

Reputation: 17818

Good news! It turns out if you create the closure over @ yourself, it works just fine:

class Test
  self = []
  constructor: (@number) ->
    self = @

  class SubTest
    constructor: (@name) ->

    toString: () ->
      @name + self.number

  getSubTest: () ->
    return new SubTest "SubTest"

test = new Test 10
v = test.getSubTest().toString()

alert v

Translates to :

var Test, test, v;

Test = (function() {
  var SubTest, self;

  self = [];

  function Test(number) {
    this.number = number;
    self = this;
  }

  SubTest = (function() {

    function SubTest(name) {
      this.name = name;
    }

    SubTest.prototype.toString = function() {
      return this.name + self.number;
    };

    return SubTest;

  })();

  Test.prototype.getSubTest = function() {
    return new SubTest("SubTest");
  };

  return Test;

})();

test = new Test(10);

v = test.getSubTest().toString();

alert(v);

Output:

SubTest10

Upvotes: 4

Related Questions