TypeScript:访问“this”的“父”函数(类似Java的MyClass.this)

时间:2016-08-09 17:11:51

标签: typescript closures this

在JavaScript中,由于数组迭代缺乏漂亮的原生语法,因此使用[].forEach((item)=>{...})非常常见; 但是,该闭包会更改this的值。

在Java中,对于这种情况,语法MyClass.this允许引用“上部”this

TypeScript中有类似的东西吗?还是在计划中?我可以想象被转换为存储this引用并在闭包中使用它。

代码:

public fromJSON(input: Object, clazz?: typeof FrameModel): T
{
    const service_this = this;
    if (clazz === void 0){
        var disc = input[GraphJSONtoTsModelsService.DISCRIMINATOR];
        if (disc instanceof Array)
            disc = disc[0];
        if (disc === void 0)
            throw new Error(`Given object doesn't specify "${GraphJSONtoTsModelsService.DISCRIMINATOR}" and no target class given: ` + JSON.stringify(input));
        clazz = this.getTypeScriptClassByDiscriminator(disc);
    }

    if (clazz == null){
        throw new Error(`No class found for discriminator ${disc}: ` + JSON.stringify(input));
    }

    let result = new FrameModel(input["_id"]);
    //result.setVertexId(input["_id"]);
    //console.log("We have a frame now: " + result);

    //for (let name in Object.getOwnPropertyNames(input) ){
    let propNames = Object.getOwnPropertyNames(input);
    for (let i = 0; i < propNames.length; i++) {
        let name = propNames[i];
        let val = input[name];
        // Properties
        if (typeof val === 'string' || typeof val === 'number'){
            let beanPropName = clazz.graphPropertyMapping[name] || name; // Use same if not defined.
            result[beanPropName] = val;
        }
        // Adjacent - input prop name is graph edge name.
        if (typeof val === 'object'){
            let beanPropName = clazz.graphRelationMapping[name] || name; // Use same if not defined.
            let info = RelationInfo.parse(beanPropName);

            //console.log(`propName: ${name}  beanPropName: ${beanPropName}  isArray: ${isArray}`);
            let direction = val["direction"];
            let items = [];
            if (val["vertices"] instanceof Array) {
                val["vertices"].forEach((vertex) => {
                    let item: Object;
                    let mode = vertex[GraphJSONtoTsModelsService.MODE] || "vertex";
                    if (mode == "vertex")
                        item = service_this.fromJSON(vertex);
                    else if (mode == "link")
                    {
                        let link: string = vertex["link"];
                        item = service_this.fromLink(link);
                    }
                    //console.log(`item: ${item}  vertex: ${JSON.stringify(vertex)}`);
                    items.push(item);
                });
            }
            result[info.beanPropName] = info.isArray ? items : (items[0]);
        }
    }

    return <T> result;
}

1 个答案:

答案 0 :(得分:1)

您没有包含您的真实代码,因此我不知道您如何运行您提到的[].forEach((item)=>{...});,但箭头功能确实保留了this的上下文。

MDN it says:

  

与函数相比,箭头函数表达式的语法更短   表达式和词汇绑定这个值......

  

箭头功能不会创建它拥有此上下文,而是它   捕获封闭上下文的this值,如下所示   代码按预期工作。

typescript docs it says

Arrow functions capture the this where the function is created rather than where it is invoked

以下是一个例子:

class A {
    private factor: number;

    constructor(factor: number) {
        this.factor = factor;
    }

    public multiply(items: number[]): number[] {
        return items.map(item => item * this.factor);
    }
}

let a = new A(2);
a.multiply([1, 2, 3, 4, 5]); // [2, 4, 6, 8, 10]

code in playground

如果这对您不起作用,请使用您遇到问题的实际代码更新您的问题。