我正在尝试装饰器,我编写了一个装饰器,该装饰器基本上返回了一个执行某些`console.log的新函数。
这是我的装饰器的外观:
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app" class="container">
<fieldset v-for="(filters, key,index) in availableFilters">
<label v-for="(count, value) in filters">
<input type="checkbox" :data-filterName="this[filters]" :value="value" v-model="selected[key]" @change="onchange"> {{value}} ({{count}})
</label>
</fieldset>
<pre>{{selected}}</pre>
</div>
这就是我的使用方式:
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
}
}
。
有什么想法吗?谢谢!
答案 0 :(得分:3)
当您要从声明函数的上下文中捕获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;
}
您可以在playground
中对其进行测试如果将此函数用作另一个函数的参数,则还应该调用bind
来为该函数设置this
(否则,调用者将确定this
的值):< / p>
router.route("/").post(testController.testIt.bind(testController))