打字稿回调函数中的“this”范围

2023-12-14

我无法理解“这个”上下文在打字稿中是如何工作的。我无法访问方法中的类成员。下面是我的代码

class adopterDetailCtrl {
    public adopter: IAdopter;
    public $router: any;

    static $inject = ['app.common.services.AdopterService'];
    constructor(private adopterService: app.common.services.IAdopterServices) {
        this.adopter = null;
    }

    $routerOnActivate(next) {
        if (next.params.id > 0) {
            this.getAdopterById(next.params.id);
        }
    }

    getAdopterById(adopterId: number): void {
        var AdopterList = this.adopterService.getAdopterById();
        AdopterList.query({ id: adopterId }, (data: adopter.IAdopter[]) => {
            this.adopter = data[0];//this.adopter is undefined here. this refers to 'window'
        });
    }

    setAdopter(data: IAdopter) {
        this.adopter = data;//can access this.adopter
    }
}

The thisTypescript 中的上下文与 JavaScript 中的上下文相同,因为您实际运行的代码是 TypeScript 编译器输出的编译后的 JavaScript。

在 javascript 中,有两种方法来处理这个问题:

  1. Use the 箭头函数
  2. Use the Function.prototype.bind 函数

你可能正在通过getAdopterById作为回调,如果是这种情况,那么使用它很容易解决bind:

let myobj = new adopterDetailCtrl(...);

...

someFunction(myobj.getAdopterById.bind(myobj));

您还可以修改构造函数中实例方法的引用:

(1)

class adopterDetailCtrl {
    public adopter: IAdopter;
    public $router: any;

    static $inject = ['app.common.services.AdopterService'];
    constructor(private adopterService: app.common.services.IAdopterServices) {
        this.adopter = null;

        this.getAdopterById = (adopterId: number) => {
            var AdopterList = this.adopterService.getAdopterById();
            AdopterList.query({ id: adopterId }, (data: adopter.IAdopter[]) => {
                this.adopter = data[0];//this.adopter is undefined here. this refers to 'window'
            });
        }
    }

    $routerOnActivate(next) {
        if (next.params.id > 0) {
            this.getAdopterById(next.params.id);
        }
    }

    getAdopterById: (adopterId: number) => void;

    setAdopter(data: IAdopter) {
        this.adopter = data;//can access this.adopter
    }
}

请注意,方法声明为空,并且使用箭头函数在 ctor 中设置实现。

(2)

class adopterDetailCtrl {
    public adopter: IAdopter;
    public $router: any;

    static $inject = ['app.common.services.AdopterService'];
    constructor(private adopterService: app.common.services.IAdopterServices) {
        this.adopter = null;

        this.getAdopterById = this.getAdopterById.bind(this);
    }

    $routerOnActivate(next) {
        if (next.params.id > 0) {
            this.getAdopterById(next.params.id);
        }
    }

    getAdopterById(adopterId: number): void {
        var AdopterList = this.adopterService.getAdopterById();
        AdopterList.query({ id: adopterId }, (data: adopter.IAdopter[]) => {
            this.adopter = data[0];//this.adopter is undefined here. this refers to 'window'
        });
    }

    setAdopter(data: IAdopter) {
        this.adopter = data;//can access this.adopter
    }
}

在 ctor 中,您重新分配边界this.getAdopterById.bind(this) to this.getAdopterById.

在这两种情况下,您都可以自由地通过getAdopterById方法作为回调而不用担心范围this.

关于箭头函数的另一个注意事项是,这是ES6,如果您不选择ES6目标在你的编译选项那么编译器实际上不会使用这个符号,而是会转换它:

class A {
    private x: number;

    fn(): void {
        setTimeout(() => console.log(this.x), 1);
    }
}

To:

var A = (function () {
    function A() {
    }
    A.prototype.fn = function () {
        var _this = this;
        setTimeout(function () { return console.log(_this.x); }, 1);
    };
    return A;
}());

这样的范围this保存在_this并在回调函数中_this.x被用来代替this.x.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

打字稿回调函数中的“this”范围 的相关文章

随机推荐