Javascript 功能装饰器重新分配提升的内部功能,无需评估
我在和你玩。我希望有一种方法可以轻松地装饰函数,而不必在声明函数的地方进行装饰Javascript 功能装饰器重新分配提升的内部功能,无需评估,javascript,eval,decorator,hoisting,Javascript,Eval,Decorator,Hoisting,我在和你玩。我希望有一种方法可以轻松地装饰函数,而不必在声明函数的地方进行装饰 var __slice = [].slice; this.around = function(decoration) { return function(base) { return function() { var argv, callback, __value__, _this = this; argv = 1 <= argume
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");
如果您愿意稍微更改约定,您可以消除
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();
如果您不愿意改变它的命名/使用方式,那么恐怕您的两个问题的答案都是否定的。我不太明白您的问题,但如果主要问题是-在装饰应用于
f
之前,我是否可以在g
顶部调用装饰的f
-我的答案是否定的。提升会使功能体在代码中的使用高于分配的功能,但装饰是一种操作,而不是一种声明,因此,它只会在运行时序列中的某一时刻发生。不,问题不在于此。这是一种非常有趣的重新定义函数的方法——实际上,这两个问题的答案似乎都是“否”。不过,仍在调查中。)@Brock,f被提升到g的顶部,装饰被添加到g,然后f被声明。在调用decorator函数之前,我不希望能够调用decordeator f。只要能让addDecorator
知道传入函数的定义位置,从而不必返回要分配给原始函数的修饰函数,我将接受更改g
的结构或调用方式的答案函数的名称。i、 e.我不想要像f=addDecorator(d,f)
这样的代码,所以我可以制作一个varadic版本:addDecorationXxToAllOf(f1,f2,f3)
@SamHasler:这两个问题的答案肯定是“不”。与全局作用域不同,JavaScript显式地不提供以某种通用方式访问函数作用域的方法。因此,您可以返回新函数值,也可以使用对象存储函数。请注意,上面的instrumentFunction
也只适用于可以访问作用域的全局函数。我想我更愿意将我的所有函数放在一个对象中,这样我就可以将对象传递给addDecorator,以避免必须进行赋值。@SamHasler也是可行的。不管怎样,我相信你必须改变你的方法来去除eval
。
function addDecorator(decoration, fn) {
var decorated = around(decoration)(fn);
decorated.unDecorate = function () {
return fn;
}
return decorated;
}
f = addDecorator(myDecorator, f);
f = f.unDecorate();