在 TypeScript 中访问外部类的成员
Posted
技术标签:
【中文标题】在 TypeScript 中访问外部类的成员【英文标题】:Access members of outer class in TypeScript 【发布时间】:2016-12-08 09:55:37 【问题描述】:从 TypeScript 1.6 开始,我们可以使用 class expressions 轻松创建内部类。在其他以 OOP 为中心的语言(如 Java)中,内部类可以访问外部类的成员 even private ones。
这种行为类似于闭包的概念,其中函数可以从定义它的范围访问变量。
为什么我不能在 TypeScript 中实现这一点? ECMAScript 2015 中的类规范在这里起作用吗?
呈现预期行为的代码:
class OuterClass
private outerField = 1337;
public InnerClass = class
public accessOuter()
return this.outerField; // outerField not defined
var outer = new OuterClass();
var inner = new outer.InnerClass();
var win = inner.accessOuter();
【问题讨论】:
请参阅***.com/a/45244695/279393 了解实现此目的的另一种方法。 【参考方案1】:如果您查看代码的已编译 javascript,就会更容易理解为什么不能这样做:
var OuterClass = (function ()
function OuterClass()
this.outerField = 1337;
this.InnerClass = (function ()
function class_1()
class_1.prototype.accessOuter = function ()
return this.outerField; // outerField not defined
;
return class_1;
());
return OuterClass;
());
如您所见,outerField
被定义为OuterClass
的成员,如下所示:
this.outerField = 1337;
当您尝试在 InnerClass
中访问它时:
return this.outerField;
但这里的this
是class_1
的实例,而不是OuterClass
,所以this
中没有outerField
。
此外,您无法从内部类访问外部类的实例。
这个在java中的解决方式是这样的:
class OuterClass
private int outerField = 1337;
public class InnerClass
public int accessOuter()
return OuterClass.this.outerField;
但 typescript/javascript 中没有与 OuterClass.this.outerField
等效的内容。
看看 typescript 内部类更像 java 中的静态内部类,但在这里你也只能访问公共属性:
class OuterClass
public static outerField = 1337; // has to be public
public InnerClass = class
public accessOuter()
return OuterClass.outerField;
您可以将外部类的实例传递给内部类:
class OuterClass
public outerField = 1337;
public InnerClass = class
constructor(private parent: OuterClass)
public accessOuter()
return this.parent.outerField;
但同样,您需要公开outerField
。
编辑
如果你想实现一些模拟所需行为的东西(也就是说,内部类实例可以访问私有的外部类成员),那么你可以这样做:
interface OuterClassProxy
outerField: number;
interface IInnerClass
class OuterClass
private outerField = 1337;
static InnerClass = class implements IInnerClass
constructor(private parent: OuterClassProxy)
public accessOuter()
return this.parent.outerField;
public createInnerClass(): IInnerClass
let outerClassInstance = this;
return new OuterClass.InnerClass(
get outerField(): number
return outerClassInstance.outerField;
,
set outerField(value: number)
outerClassInstance.outerField = value;
);
这是相当多的工作,但它会做到的。
【讨论】:
【参考方案2】:@Nitzan 的回答很棒。我只是想补充一下,我最近想出了这个,也许它有帮助:
class Outer
constructor()
this.val = 1337;
get Inner()
let Outer = this;
return class
accessVal() return Outer.val;
new (new Outer()).Inner().accessVal(); // 1337
【讨论】:
为使用它的内部类添加一个接口可能是个好主意【参考方案3】:这是在 Typescript 中执行此操作的正确方法:
class OuterClass
private outerField = 1337;
get InnerClass()
const thatOuterField = this.outerField // <-- Notice this addition
return class
public accessOuter()
return thatOuterField; // outerField not defined
let outer = new OuterClass();
let inner = new outer.InnerClass();
let win = inner.accessOuter();
alert(win); // test works!
不需要任何复杂的东西。
【讨论】:
这是 Kosmas 6 个月前发布的相同方法 虽然你不能修改 outerField...【参考方案4】:这个对我来说并没有那么糟糕:
function use<T>(value: T) return new class with<U>(f: (value: T) => U) return f(value)
class OuterClass
private outerField = 1337;
InnerClass = use(this).with(outerThis => class
accessOuter()
return outerThis.outerField; // outerField not defined
const outer = new OuterClass()
const inner = new outer.InnerClass()
const win = inner.accessOuter()
console.log(win)
【讨论】:
以上是关于在 TypeScript 中访问外部类的成员的主要内容,如果未能解决你的问题,请参考以下文章