我在使用Typescript时遇到问题,其中this
关键字在调试时显示为未定义,因此,不调用从回调方法调用的某些私有类方法。我的文本编辑器似乎认为我的引用很好并且给了我intellensense,所以我认为代码是可以的。下面是一个缩短的例子。调用cacheUser
回调方法时,_processSuccessfulRegistration
和_handleCreationResponse
不会被点击。
export class User extends Observable {
public email: string;
public password: string;
public username: string
constructor() {
super()
this.email = '';
this.password = '';
this.username = '';
}
public register() {
let user = {
// build out object
}
userService.createAccount(user)
.catch(/* handle error */)
.then(this._handleCreationResponse)
}
private _handleCreationResponse(response) {
let status = response.status;
let userData = response.result;
switch (status) {
case ApiStatus.Success:
this._cacheUser(userData);
this._processSuccessfulRegistration(userData);
break;
case ApiStatus.SomeError:
// handle errors
break;
default:
// do something else
break;
}
}
private _cacheUser(user) {
// handle user caching
}
private _processSuccessfulRegistration() {
// call some other services and
// navigate to a new view
}
}
答案 0 :(得分:3)
当您将函数作为回调传递时,函数不会绑定到特定的this
,因此当它们被执行时this
将引用其他内容。
为避免您bind the function:
userService.createAccount(user)
.catch(/* handle error */)
.then(this._handleCreationResponse.bind(this)
或使用arrow function确保为此保存正确的上下文:
userService.createAccount(user)
.catch(/* handle error */)
.then(response => this._handleCreationResponse(response))
还有另一个选项是创建此方法作为箭头函数开始:
private _handleCreationResponse = (response) => {
let status = response.status;
let userData = response.result;
switch (status) {
case ApiStatus.Success:
this._cacheUser(userData);
this._processSuccessfulRegistration(userData);
break;
case ApiStatus.SomeError:
// handle errors
break;
default:
// do something else
break;
}
}
然后你可以像以前那样传递它,并保留this
的上下文
如果使用此选项,请注意它与之前的有点不同,因为_handleCreationResponse
将不再是方法,而是实例的函数属性(也就是说,它不会是原型的一部分) )。
这是一个显示差异的简短示例:
class MyClass {
method1() {
console.log("method 1");
}
method2 = () => {
console.log("method 2");
}
}
编译为:
var MyClass = (function () {
function MyClass() {
this.method2 = function () {
console.log("method 2");
};
}
MyClass.prototype.method1 = function () {
console.log("method 1");
};
return MyClass;
}());
你不能覆盖扩展类中箭头函数的方法,但是因为你的方法是私有的,所以它应该不是问题。