Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 访问TypeScript中外部类的成员_Oop_Typescript_Closures_Inner Classes - Fatal编程技术网

Oop 访问TypeScript中外部类的成员

Oop 访问TypeScript中外部类的成员,oop,typescript,closures,inner-classes,Oop,Typescript,Closures,Inner Classes,由于TypeScript1.6,我们可以轻松地使用创建内部类。在其他以OOP为中心的语言(如Java)中,内部类可以访问外部类的成员 这种行为类似于闭包的概念,函数可以从定义它的范围访问变量 为什么我不能在TypeScript中实现这一点?ECMAScript 2015中的类规范在这里起作用吗 表示预期行为的代码: class OuterClass { private outerField = 1337; public InnerClass = class {

由于TypeScript1.6,我们可以轻松地使用创建内部类。在其他以OOP为中心的语言(如Java)中,内部类可以访问外部类的成员

这种行为类似于闭包的概念,函数可以从定义它的范围访问变量

为什么我不能在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();

如果您查看代码的已编译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;
当您尝试在
内部类中访问它时,您会:

return this.outerField;
但是
this
这里是
class_1
的实例,而不是
OuterClass
,因此
中没有
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
public


编辑 如果希望实现模拟所需行为的功能(即,内部类实例将有权访问私有外部类成员),则可以执行以下操作:

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;
            }
        });
    }
}

这是相当多的工作,但它会做到的。

@Nitzan的答案很好。我只是想补充一下,我最近提出了这个,也许它有帮助:

class Outer {

    constructor() {
        this.val = 1337;
    }

    get Inner() {
        let Outer = this;
        return class {
            accessVal() { return Outer.val; }
        }
    }

}

new (new Outer()).Inner().accessVal(); // 1337

以下是在Typescript中执行此操作的正确方法:

类外部类{
专用外场=1337;
获取内部类(){

const thaturefield=this.outerField/这一个对我来说没那么坏:

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)
函数用法(value:T){返回新类{with(f:(value:T)=>U){返回f(value)}}
类外类{
专用外场=1337;
InnerClass=使用(this).with(outerThis=>class{
accessOuter(){
返回outerThis.outerField;//未定义outerField
}
}
}
const outer=新的OuterClass()
const inner=新的outer.InnerClass()
const win=internal.accessOuter()
console.log(win)

为使用它的内部类添加接口可能是个好主意。请参阅其他实现方法。这与Kosmas 6个月前发布的方法相同