我正在玩function decorators 。我希望有一种方法可以轻松地装饰函数而不必在声明函数的地方进行。
var __slice = [].slice;
this.around = function(decoration) {
return function(base) {
return function() {
var argv, callback, __value__,
_this = this;
argv = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
__value__ = void 0;
callback = function() {
return __value__ = base.apply(_this, argv);
};
decoration.apply(this, [callback].concat(argv));
return __value__;
};
};
};
f("from outer");
function f(a){
console.log("f OUTER",a);
};
f("from outer");
(function g(){
f("from Inner (hoisted)");
function addDecorator(decoration, fn) {
var decorated = around(decoration)(fn);
eval(fn.name + " = decorated");
decorated.unDecorate = function (){
eval(fn.name + " = fn");
}
}
function myDecorator(cb){
console.log("before");
cb();
console.log("after");
}
function f(a){
console.log("f INNER",a);
}
f("from Inner (after declaration)");
addDecorator(myDecorator, f);
f("from Inner (Decorated)");
f.unDecorate();
f("from Inner (Undecorated)");
})();
f("from outer");
我希望能够在 g
内的任何位置调用 addDecorator
。即在顶部,f
被提升到其声明之上。
在 Chrome 的控制台中,我得到以下输出:
f OUTER from outer
f OUTER from outer
f INNER from Inner (hoisted)
f INNER from Inner (after declaration)
before
f INNER from Inner (Decorated)
after
f INNER from Inner (Undecorated)
f OUTER from outer
- 这可以在不进行评估的情况下完成吗?
- addDecorator可以移到g之外吗? (没那么重要)
最佳答案
如果您愿意稍微改变一下约定,则可以消除 eval
并将函数移至 g
之外。
这将具有相同的效果,但调用方式略有不同:
function addDecorator(decoration, fn) {
var decorated = around(decoration)(fn);
decorated.unDecorate = function () {
return fn;
}
return decorated;
}
f = addDecorator(myDecorator, f);
f = f.unDecorate();
如果您不愿意改变它的调用/使用方式,那么恐怕您的两个问题的答案都是“否”。
关于javascript - 函数装饰器在没有 eval 的情况下重新分配提升的内部函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24456122/