为什么我在这段代码中失去了上下文

Why do I lose context in this code?

本文关键字:失去 上下文 代码 段代码 为什么      更新时间:2023-09-26

下面是我在使用展开运算符时丢失上下文的代码。

看函数"decorator"。当我失去上下文时,行被标记为"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);,所以为什么我的上下文丢失了?

据我所知,originDesc(…args);= originDesc。应用(这个参数);那么,为什么上下文丢失了呢?

不,没有。它相当于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);

这是因为你设置了:

let originDesc = desc.value; // This is where you loose context
,然后调用originDesc。这与这里描述的情况完全相同:如何在回调中访问正确的' This '上下文?

同样,originDesc(...args)编译成originDesc.apply(void 0, args)。(void因为它没有上下文绑定,你可以在https://www.typescriptlang.org/play/上测试它)