NodeJS函数/模块包含范围

我正在开发一个应用程序与node.js和socket.io。 我已经在一个连接特定的块中build立了一个包含一些variables和函数的小规模项目。 这些函数可以访问在该块中声明的variables,而不需要特别地传递值。

这工作正常,并可以接受这个规模的项目。 但是,当我试图清理代码时,我考虑将这些函数分解到它们自己的文件中,并使用exports.functionname来声明模块,如下所述: http : //nodejs.org/docs/v0。 3.2 / API / modules.html

但是,这些函数在require()'d in而不是实际在文件中声明时通常不会访问同一块中的variables。

有什么方法可以使外部文件中的函数像在nodejs中本地声明一样吗?

有没有黑客模块系统,这正是我所做的。 https://github.com/Benvie/Node.js-Ultra-REPL/blob/master/lib/ScopedModule.js

我不能说我推荐它用于生产。 基本上这个问题更多的是JavaScript本身。 节点将模块封装在一个函数中,以便它们拥有自己的专用范围。 在该范围内共享的唯一方式是在该function内部执行,这对于模块(模块化…)系统来说并不真正起作用。 唯一的其他范围是全球性的也是不可取的。

我用来解决这个问题的技巧是改变包装函数的基础上的dynamic属性的外部定义的模块导入,以便从模块包装内所有这些参数看起来像他们神奇的定义,但不是全球性的。

节点的模块包装看起来像这样:

(function (exports, module, require, __filename, __dirname){ /**module**/ }) 

我的地方只是添加更多的参数,并确保在执行模块包装之前解决它们。

我已经在加载模块之前在给定的文件夹中读取名为“.deps.json”的文件。 一个例子就是这样

 [{ "providers": [ "./utility/", "./settings/" ], "receivers": [ "*" ] }] 

因此,它将加载这些子文件夹中的模块,然后将每个模块公开为封装器中的一个参数,并以文件名命名。

通常的干净的方法是在模块中定义一个函数,它将所需的variables作为参数:

 // extracted_file.js exports.handler = function(param1, param2) { return param1 + param2; } // caller file var extractedHandler = require('./extracted_file').handle; var localVar1 = 1300, localVar2 = 37; console.log(extractedHandler(localVar1, localVar2)); 

您可以使用toString()和可怕的eval来更改函数作用域。

如果你的函数在说lib.js如下:

 var lib = {} lib.foo = function() { console.log(var1) } lib.bar = function() { console.log(var2) } module.exports = lib 

在main.js中你可以有这个:

 var var1 = 1 var var2 = 2 var ob1 = require('./lib') ob1.foo() ob1.bar() 

当你运行它ob1.foo()行给出一个ReferenceError,var1没有定义。 这是因为foo()的作用域来自lib.js而不是你的主js文件,而var1对它来说是不可见的。 ob1.foo是对lib.js作用域的函数的引用。 您需要使用main.js作用域进行新的引用。

要做到这一点每个函数转换为string和评估它。 这将创build一个具有相同代码但main.js作用域的新函数。 下面是使用setMainScope方法的一种方法,它循环遍历所有将其作用域改为main.js的函数。

 var var1 = 1 var var2 = 2 var ob1 = {} ob1.setMainScope = function(ob2) { for(var prop in ob2) { if( !ob2.hasOwnProperty(prop) ) {continue} if( typeof ob2[prop] !== 'function' ) {continue} this[prop] = eval( "(" + ob2[prop].toString() + ")" ) } } ob1.setMainScope( require('./lib') ) ob1.foo() // 1 ob1.bar() // 2 

现在除了使用eval以外,它都可以正常工作。 foo()bar()的作用域现在是main.js,所以它们看到了var1var2