2016-11-08 5 views
1

Вот код, где я теряю контекст при использовании оператора спреда.Почему я теряю контекст в этом коде?

Посмотрите на функцию «декоратор». Линия, когда я теряю контекст отмечен «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); так почему мой контекст потерял?

ответ

1

Насколько я понимаю originDesc (... арг); равно originDesc.apply (это, аргументы); поэтому почему контекст потерян?

Нет, это не так. Это эквивалентно 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); 
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/)

Смежные вопросы