【问题标题】:Capture caller's scope in JavaScript在 JavaScript 中捕获调用者的作用域
【发布时间】:2012-09-16 03:01:54
【问题描述】:

此代码在运行 eval 的同一范围内工作:

function compile(fn) {
    //Actually calls fn.toString() then compiles some es.next type 
    //features to current versions of es.
    return 'function () { return a; }';
}

function runAsStringA() {
    var a = 10;
    var compiled = eval(compile());
    return compiled();
}

这不起作用,但符合我在理想世界中想做的事情:

function compile(fn) {
    return eval('function () { return a; }');
}

function runAsStringA() {
    var a = 10;
    var compiled = compile();
    return compiled();
}

基本上我需要一种在父级范围内进行评估的方法。

我试过了:

function compile(fn) {
    return eval.bind(this, 'function () { return a; }');
}

function runAsStringA() {
    var a = 10;
    var compiled = compileSpecialFunction()();
    return compiled();
}

问题是编译后的函数在作用域内没有得到a

我正在尝试在 node.js 环境中使用它,所以如果解决方案仅适用于 node.js 就可以了

它甚至可能需要一些本机代码,尽管我没有编写本机插件的经验。

【问题讨论】:

  • 你看过the vm module吗?
  • @FelixKling 我需要这个,因为我正在尝试将 JavaScript 交叉编译到 JavaScript 以添加一个 await 关键字,该关键字大致相当于 C# 的 await 并与 Q Promise 一起使用。这有点难看,但除此之外我已经让它工作得很好。目前我只在 node.js 中使用它,所以我可以通过将模块提供给我的编译函数来传递通常可用于模块的所有本地变量。
  • @OcuS 一般来说,eval 是邪恶的,但是在一些特殊的高级场景中,如果没有它,您将无法复制某些功能(除非有人能找到一种方法)。我要做的是至少封装 eval 的使用,这样它就不会暴露给我的组件的消费者,因为那真的是邪恶的。
  • 是的@Zirak,这是一个很酷且有用的模块,但不幸的是似乎没有办法以我想要的方式选择范围。

标签: javascript node.js eval


【解决方案1】:

不幸的是,这似乎是不可能的。

【讨论】:

    【解决方案2】:

    虽然我同意您应该避免使用eval,并且可能避免使用veal(正如我的拼写检查器所建议的那样),但这可能会有所帮助:

    function compile(a) {
        return eval('(function(a) { return a; })').call(this, a);;
    }
    
    function runAsStringA() {
        var a = 10;
        var compiled = compile(a);
        return compiled;
    }
    
    console.log(runAsStringA());
    

    【讨论】:

    • 问题是我不知道它只是一个,它可能是范围内的任何变量。
    • 你能让你的变量成为范围的成员吗?例如this.a = 10; 而不是 var a = 10; ?
    • 不,我需要将函数编译为字符串,但让它的工作方式与常规 JavaScript 完全一样。
    猜你喜欢
    • 1970-01-01
    • 2011-02-19
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-07
    相关资源
    最近更新 更多