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?
If you want your inner class to access outer class instance variables then in the constructor for the inner class, include an argument that is a reference to the outer class instance. The outer class invokes the inner class constructor passing this as that argument.
Method Local inner classes can't use a local variable of the outer method until that local variable is not declared as final. For example, the following code generates a compiler error.
You need to pass in the parent (since there's no outer keyword), but the inner class can access private members of the parent.
Unlike inner class, a static nested class cannot access the member variables of the outer class. It is because the static nested class doesn't require you to create an instance of the outer class.
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
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With