javascript - 函数装饰器在没有 eval 的情况下重新分配提升的内部函数

标签 javascript eval decorator hoisting

我正在玩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 
  1. 这可以在不进行评估的情况下完成吗?
  2. 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();

http://jsfiddle.net/8SuT9/1/

如果您不愿意改变它的调用/使用方式,那么恐怕您的两个问题的答案都是“否”。

关于javascript - 函数装饰器在没有 eval 的情况下重新分配提升的内部函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24456122/

相关文章:

javascript - 离开页面前的对话操作

php - 做一个文本变量的数学总和? (例如 5865/100 )

python - 清理 Streamlit 中特定功能的 test.cache

javascript - 设置 Safari Web 预览的缩略图

javascript - 对 MongoDB 的重复 Node.js 请求最终会变慢

python - 值错误: unknown type object pandas eval for n rows => 100

javascript - 在运行 jQuery 时使用 eval() 在 for() 中创建动态变量的替代方法?

python - 装饰器与继承

typescript - 是否可以在 Typescript 中装饰装饰器?

javascript - “Thinking in AngularJS”,如果我有jQuery背景?