【问题标题】:Access local variables context of nodejs main from included eval script从包含的 eval 脚本访问 nodejs main 的局部变量上下文
【发布时间】:2023-12-19 23:47:01
【问题描述】:

我发现以下方法可以很方便地包含 nodejs 文件,而无需将它们转换为模块。只有一个小警告。我宁愿不必在 main.js 中将我的 var 更改为 global,以便可以通过 included.js 文件访问它。正如您在包含的文件中看到的那样,我不必这样做。我的主要变量可以访问那里的变量。见代码。是否有某种方式可以在包含的文件中访问节点主文件的本地上下文,而无需将所有 var.* 更改为 global.* 如果我希望它们通过包含访问。

这里是代码

//主文件

//evalmain.js
var vm = require('vm');
var fs=require("fs");

global.globalVar = 0;  //<<-- *** Prefer var globalVar***

// Include the script 
var script = new vm.Script(fs.readFileSync(__dirname+"\\evalinc.js"+""));
script.runInThisContext();

console.log("globalVar: ", globalVar, "  evalVar: ", evalVar);
showvars();
console.log("globalVar: ",++globalVar, "  evalVar: ", evalVar);
evalVar="Now set in evalmain";
showvars();

//包含文件

// evalinc.js is the file to be included
// Note, it's not a module. Just plain JS
debugger;
globalVar=100; // Sets the global variable at main!
var evalVar="Set in evalinc!";
var showvars=function(){
    console.log("globalVar: ",++globalVar, "  evalVar: ", evalVar);
}

【问题讨论】:

    标签: node.js include eval


    【解决方案1】:

    不,局部变量上下文不能以编程方式访问。但是,您可以创建一个专用对象,该对象将成为脚本的上下文:

    var vm = require('vm');
    var fs=require("fs");
    
    var globals = {
        globalVar: 0
    }; // not a global variable
    
    // Include the script 
    var script = new vm.Script(fs.readFileSync(__dirname+"\\evalinc.js"+""));
    script.runInNewContext(globals);
    
    console.log("globalVar: ", globals.globalVar, "  evalVar: ", globals.evalVar);
    globals.showvars();
    console.log("globalVar: ", ++globals.globalVar, "  evalVar: ", globals.evalVar);
    globals.evalVar="Now set in evalmain";
    globals.showvars();
    

    【讨论】:

    • 还有很多其他方法可以给猫剥皮。我正在寻找一种不修改我的代码或包含/评估代码的方法。我的解决方案更简单,因为我所要做的就是修改代码中的全局变量声明。即 var globalVar =0 --> 全局。 globalVar = 0。更有趣的是,您可以删除 var 声明并将变量初始化为 globalVar=0,您将获得相同的效果。但仍然修改代码。通过对节点的所有自省,您会认为有一种方法可以以编程方式访问本地上下文。
    • 不,我不认为有办法做到这一点。
    【解决方案2】:

    您尝试过简单的eval 吗?我猜它完全符合您的期望,即使不影响全局范围。

    var fs=require("fs");
    
    var globalVar = 0;
    
    eval(fs.readFileSync(__dirname+"\\evalinc.js")); // Include the script 
    
    console.log("globalVar: ", globalVar, "  evalVar: ", evalVar);
    showvars();
    console.log("globalVar: ", ++globalVar, "  evalVar: ", evalVar);
    evalVar = "Now set in evalmain";
    showvars();
    

    【讨论】:

      最近更新 更多