以下是使用扩展运算符时丢失上下文的代码。
看功能“装饰”。丢失上下文时的行标有“ERROR”
/** MethodDecorator example */
class Account {
public firstName: string;
public lastName: string;
public constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
@decorator
public sayMessage(msg: string): string {
return `${this.firstName} ${this.lastName}: ${msg}`
}
}
function decorator(target: any, key: string, desc: any): any {
let originDesc = desc.value;
desc.value = function(...args: any[]): any {
return originDesc(...args); // ==> ERROR: context lost
//return originDesc.apply(this, arguments); // ==> all OK
};
return desc;
}
let persone = new Account('John', 'Smith');
let message = persone.sayMessage('Hello world!');
console.log(message); // ==> undefined undefined: Hello world!
据我所知,originDesc(...args);
等于originDesc.apply(this, arguments);
,为什么我的背景会丢失?
答案 0 :(得分:1)
那是因为你设置了:
let originDesc = desc.value; // This is where you loose context
然后拨打originDesc
。这与此处描述的情况完全相同:How to access the correct `this` context inside a callback?。
此外,originDesc(...args)
会编译为originDesc.apply(void 0, args)
。 (void
因为它没有上下文绑定,您可以在https://www.typescriptlang.org/play/)
答案 1 :(得分:1)
据我了解originDesc(... args);等于originDesc.apply(this,arguments);为什么背景会丢失?
不,它没有。它相当于originDesc(args[0], args[1], /*etc.*/)
,它使用默认的this
(松散模式下的全局对象,严格模式下为undefined
)。
在该代码中,您需要使用.apply
:
originDesc.apply(appropriateThisValueHere, args);
或.call
:
originDesc.call(appropriateThisValueHere, ...args);
根据代码中的这条评论:
//return originDesc.apply(this, arguments); // ==> all OK
appropriateThisValue
将为this
,因此:
originDesc.apply(this, args);
或
originDesc.call(this, ...args);