【问题标题】:Incorrect object "this" on context [duplicate]上下文中的对象“this”不正确[重复]
【发布时间】:2021-10-16 03:24:38
【问题描述】:

我在以下结构的辅助类中丢失了“This”对象的上下文,我不知道为什么。

在 getAll 方法中,this 对象正在引用位于主组件的 servicesDict 数组中的对象。 p>

我希望 this 对象引用 Entity1Utils 类。

export class Entity1Utils {
    public getAll(context) {
        this.buildQueryParams();
        // this "this" refers to the object { id: 'entity1', method: this.entity1Utils.getAll }
        // located on servicesDict at ManagementComponent
    }

    private buildQueryParams() {
        // logical code
    }
}


@Component({
    selector: 'app-management',
    templateUrl: './management.component.html',
    styleUrls: ['./management.component.css']
})

export class ManagementComponent implements OnInit {
    private entity1Utils: Entity1Utils;
    private servicesDict: any;

    constructor() {
        this.entity1Utils = new Entity1Utils();

        this.servicesDict = [
            { id: 'entity1', method: this.entity1Utils.getAll }
        ];
    }
}

【问题讨论】:

  • 对不起,我不太明白你在说哪个this,它指向哪里以及你希望它指向哪里。

标签: javascript angularjs typescript


【解决方案1】:

一般来说,函数内的范围(this 指向的内容)由调用该方法的对象决定。

foo.doSomething() // inside doSomething, 'this' is foo
const method = foo.doSomething;
method(); // 'this' is undefined
const obj = { method: foo.doSomething }
obj.method() // 'this' is obj

您正在传递对 方法本身的引用,该引用与您的类的实例分离:

{ method: this.entity1Utils.getAll } // the getAll method itself

所以当下游调用它时,它会作为 servicesDict 上的方法调用它:

const service = serviceDict[0];

// 'getAll' invoked on the serviceDict entry, so inside
// the method 'this' points to the serviceDict entry
service.method() 

您可以通过将方法设为箭头函数来解决此问题,将其绑定到当前范围:

getAll = context => { ... }

或者通过创建一个新的匿名内联箭头函数来保留范围:

{ method: (...args) => this.entity1Utils.getAll(...args) }

或者通过显式绑定:

{ method: this.entity1Utils.getAll.bind(this.entity1Utils) }

【讨论】:

  • 不错!我以前遇到过这个问题,但没有一个解释像你的那样干净。现在我知道了上下文是如何工作的。谢谢。
  • @PatrickFreitas 你使用了哪种方法,Patrick,因为上面的绑定不会按要求绑定到 Entity1Utils 实例,它会绑定到 ManagementComponent 实例。此处建议的修复都不能满足您的要求。
  • @MikeM 我实际上采用了上面提到的最后一种方法,现在才弄清楚这正是你的建议。
  • 糟糕。对不起。我忽略了entity1Utils 位。更新了答案以解决它。
  • @PatrickFreitas 我建议在Entity1Utils 中进行绑定,这样它的用户就不必处理绑定问题。有什么理由不应该绑定吗?
【解决方案2】:

嗯,你可以使用bind,例如:

method: this.entity1Utils.getAll.bind(this.entity1Utils)

【讨论】:

    猜你喜欢
    • 2013-10-16
    • 1970-01-01
    • 2014-11-11
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多