10

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?

0

2 Answers 2

4

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

Sign up to request clarification or add additional context in comments.

6 Comments

Well, passing number as an argument to constructor is possible solution, of course, but not the one I need. I would like not to pass any additional arguments to inner class constructor, as I need some universal solution, allowing me to access any of possibly big number of outer class fields. However, thank you for the answer.
@Leaom The problem is the way coffescript encapsulates the inner class off, so I'm afraid this behavior is by design.
@Leaom See my new edit, I think I found a good workaround for you.
Oh, that looks great! I think it perfectly solves my problem. Thanks a lot!
I hope an expert like @TrevorBurnham might drop by and offer some further insight or possibly a cleaner solution.
|
1

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()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.