Typescript中this的子作用域问题

Issue with child scoping of this in Typescript

本文关键字:作用域 问题 this Typescript      更新时间:2023-09-26

这个和我读过的其他this范围界定问题几乎是一样的,除了一个细微的区别,这使得问这个问题是相关的。

现在最初我的问题是this与Knockout和Typescript的范围,所以给出以下内容:

class ViewModel
{
    public SomeObservableArray = new ko.observableArray();
    public AddToTheObservableArray(someJsonData: any) 
    {
        this.SomeObservableArray.push(new SomePojo(someJsonData));
    }
}

所以上面代码中的this位会爆炸,因为Typescript让你认为this是类实例,但实际上它是其他的,这是因为ajax回调或视图元素,无论场景覆盖this关键字。

所以为了解决这个问题,大多数解决方案是将这些代码移到类的构造函数中,我个人觉得这很可怕,但是考虑到我从使用TypeScript中获得的其他好处,这一点可怕是可以接受的。下面的代码修复了上面的问题:
class ViewModel
{
    public SomeObservableArray = new ko.observableArray();
    public AddToTheObservableArray = (someJsonData: any) => Void;
    constructor
    {
        this.AddToTheObservableArray = (someJsonData: any) => {
            this.SomeObservableArray.push(new SomePojo(someJsonData));
        };
    }
}

我只是在脑海中写下这个示例代码,所以我为任何拼写错误等道歉,但它突出了面临的常见问题和常见的解决方案/工作。

现在!问题是从这里开始的下一步,我有这样的代码:

class ViewModel
{
    public SomeObservableArray = new ko.observableArray();
    public AddToTheObservableArray = (someJsonData: any) => Void;

    constructor
    {
        this.PopulateObservableArray = (someJsonArrayData: any) => {
            this.SomeObservableArray.removeAll();
            someJsonArrayData.forEach(function(someJsonData) {
                this.SomeObservableArray.push(new SomePojo(someJsonData));
            });
        };
    }
}
输出的代码如下所示:
var ViewModel = (function(){
    function ViewModel(){
        var _this = this;
        this.SomeObservableArray = new ko.observableArray();
        this.AddMultipleEntitiesToObservableArray = function(someJsonArrayData) {
            _this.SomeObservableArray.removeAll();
            someJsonArrayData.forEach(function(someJsonData) {
                this.SomeObservableArray.push(new SomePojo(someJsonData));
            });
        }
    };
    return ViewModel;
})();

我再次为任何拼写错误道歉,因为我只是简化了较大的项目输出,但是这里要看到的主要事情是forEach方法子this仍然存在,所以我得到了错误this.SomeObservableArray is undefined

我确信1可能的解决方案是提取foreach并使其成为自己的方法,但是这感觉就像在黑色上贴胶带,所以我想知道是否有一些更优雅的解决方案或我的部分错误,可以更改为至少不必使其更加不可读。

有,而且实际上很简单。只要在任何方法上使用lambda表达式,您希望将其作用域限定为更高级函数的作用域。在您的情况下,您需要将示例重写为:

class ViewModel
{
    public SomeObservableArray = new ko.observableArray();
    public AddToTheObservableArray = (someJsonData: any) => Void;

    constructor()
    {
        this.PopulateObservableArray = (someJsonArrayData: any) => {
            this.SomeObservableArray.removeAll();
            someJsonArrayData.forEach((someJsonData) => {
                this.SomeObservableArray.push(new SomePojo(someJsonData));
            });
        };
    }
}

PS:最好不要在a中为each操作可观察数组,因为该数组的订阅者将在每次更改时收到通知。只需将数据推送到临时数组,然后将该数组设置为可观察数组的值(只是我的2cts)