使用方法作为筛选器的回调函数会影响回调的范围



我在 angular 中遇到了一个问题,我的方法被调用为回调函数而失去了范围。有人可以解释为什么this更改为undefined吗?

@Component({...})
export class SomeClass {
public status = 'any';
public filter_account_accesses() {
console.log( this.status );
let account_accesses = [...];
return account_accesses.filter( this.status_filter )
}
private status_filter( account_access ): boolean {
console.log( typeof this );
// this is undefined!
return true;
}
}

PS:我已经知道我可以通过传递this作为论据来解决这个问题。我想知道为什么会发生范围的变化。以及可选的我如何防止它。

函数中this的值取决于该函数的调用方式。让我们看一个简单的例子:

function A() {}
A.prototype.foo = function() {
// do something
}
const a = new A();

如果像这样调用foo,则 this inside 的值将是a对象:

a.foo();

但是,如果将对foo函数的引用存储到其他变量,则它不再绑定到a实例,并且其值将未定义:

const f = a.foo;
f(); // <- value of this inside is undefined

这类似于您在代码片段中执行的操作:您将对实例方法的引用传递给 filter 函数status_filter并且它没有绑定到您的实例,这就是为什么当调用filter回调时,这个内部的值是未定义的。

您可以使用bind将函数绑定到您的实例:

return account_accesses.filter( this.status_filter.bind(this) )

它将创建函数的副本,其中this指向您的实例。

另外,我向你推荐这篇关于this如何在JS中工作的伟大而全面的文章:http://dmitrysoshnikov.com/ecmascript/chapter-3-this/

因为你的函数是用数组过滤器调用的。有两种方法可以在不丢失this的情况下做到这一点:

  1. 使用箭头功能
return account_accesses.filter(value => this.status_filter(value));
  1. 使用bind
return account_accesses.filter(this.status_filter.bind(this));

最新更新