Zurab-D Zurab-D - 24 days ago 8
TypeScript Question

Why do I lose context in this code?

Here is a simple code in wich I lose context when using spread operator.

Look at function "decorator". Line when I lose context is marked with "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!


As far as I understand
originDesc(...args);
equals
originDesc.apply(this, arguments);
so why context is lost?

Answer

As far as I understand originDesc(...args); equals originDesc.apply(this, arguments); so why context is lost?

No, it doesn't. It's equivalent to originDesc(args[0], args[1], /*etc.*/), which uses the default this (the global object in loose mode, undefined in strict mode).

In that code, you'll need to use .apply:

originDesc.apply(appropriateThisValueHere, args);

or .call:

originDesc.call(appropriateThisValueHere, ...args);

According to this comment in the code:

 //return originDesc.apply(this, arguments); // ==> all OK

appropriateThisValue would be this, so either:

originDesc.apply(this, args);

or

originDesc.call(this, ...args);
Comments