декораторы: "this" не определено при доступе в descriptor.value - PullRequest
0 голосов
/ 19 декабря 2018

Я пробую декораторы, я написал декоратор, который в основном возвращает новую функцию, которая делает `console.log.

Вот как выглядит мой декоратор:

function test(target, name, descriptor) {
    const original = descriptor.value;
    console.log("bbau");
    if (typeof original === 'function') {
        descriptor.value = function (...args) {
            console.log(`Arguments: ${args}`);
            try {
                console.log("executing");
                const result = original.apply(this, args);
                console.log("done");
                console.log(`Result: ${result}`);
                return result;
            } catch (e) {
                console.log(`Error: ${e}`);
                throw e;
            }
        }
    }
    return descriptor;
}

И вот как я это использую:

class TestController extends BaseController<//..> {
    // ... 
    @test
    testIt(req: Request, res: Response) : Response {
       this.sendResponse();
    }

    sendResponse(options: ISendResponseOptions, res: Response) : Response {
       // return response
    }
}

`` Однако при выполнении возникает ошибка: Error: TypeError: Cannot read property 'sendResponse' of undefined.

Есть мысли о том, что это может быть?Спасибо!

1 Ответ

0 голосов
/ 19 декабря 2018

Обычно вы должны использовать функцию со стрелкой, если хотите захватить this из контекста, в котором вы объявили функцию (или когда this не имеет значения).В этом случае вы действительно хотите, чтобы this был объектом, к которому была вызвана функция, поэтому вы должны использовать обычную функцию:

const test = (target, name, descriptor) => {
    const original = descriptor.value;
    if (typeof original === 'function') {
          descriptor.value = function (...args) {
            console.log(`Arguments: ${args}`);
            try {
                console.log("executing");
                const result = original.apply(this, args);
                console.log("done");
                console.log(`Result: ${result}`);
                return result;
            } catch (e) {
                console.log(`Error: ${e}`);
                throw e;
            }
        }
    }
    return descriptor;
}

Вы можете проверить это на детской площадке

Если вы используете эту функцию в качестве параметра для другой функции, вам также следует вызвать bind для установки this для функции (в противном случае вызывающая сторона определит значение this):

router.route("/").post(testController.testIt.bind(testController))
...