NodeJS 函数/模块包含范围
我正在使用node.js 和socket.io 开发一个应用程序。我已经构建了一个小型项目,在特定于连接的块内包含一些变量和函数。这些函数可以访问该块中声明的变量,而无需专门传递值。
这工作得很好,对于这种规模的项目来说是可以接受的。然而,当我试图清理一下代码时,我研究了将这些函数分解到它们自己的文件中,并找到了使用exports.functionname声明的模块,如下所述:http://nodejs.org/docs/v0.3.2/api/modules.html
但是,这些函数没有访问权限与它们位于同一块中的变量通常是在 require() 中而不是在文件中实际声明时执行的。
有没有某种方法可以使外部文件中的函数的行为就像在 Nodejs 中本地声明的一样?
I'm developing an application with node.js and socket.io. I have built a small-scale project with some variables and functions inside a connection-specific block. These functions have access to the variables declared within that block without the need to pass the values in specifically.
This works fine, and is acceptable for a project of this size. However, as I was trying to clean the code up a bit, I looked into factoring those functions out into their own file and found modules declared by using exports.functionname as described here: http://nodejs.org/docs/v0.3.2/api/modules.html
However, these functions do not have access to the variables within the same block as they normally do when being require()'d in instead of actually being declared in the file.
Is there some way to make functions in an external file behave as if they were declared locally in nodejs?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果不破解模块系统,就不可能实现这一点,这正是我所做的。 https://github.com/Benvie/Node .js-Ultra-REPL/blob/master/lib/ScopedModule.js
我不能说我推荐它用于生产。基本上问题更多的是 JavaScript 本身。 Node 将模块包装在函数中,因此它们有自己的私有范围。在该范围内共享的唯一方法是在该函数内执行,这对于模块(模块化...)系统来说实际上不起作用。唯一的其他范围是全局的,这也是不可取的。
我用来解决这个问题的技巧是更改包装器函数,使其具有基于外部定义的一组模块导入的动态属性,以便从模块包装器内部看,所有这些参数看起来像是被神奇地定义的,但不是全局的。
Node 的模块包装器如下所示:
我的模块包装器只是添加更多参数并确保它们在执行模块包装器之前得到解决。
在加载模块之前,我让它读取给定文件夹中名为“.deps.json”的文件。
一个示例如下所示,
因此它将加载这些子文件夹中的模块,然后将每个模块公开为包装器中的参数,并根据文件名命名。
There isn't without hacking the module system, which is exactly what I did. https://github.com/Benvie/Node.js-Ultra-REPL/blob/master/lib/ScopedModule.js
I can't say I recommend it for production. Basically the issue is more with JavaScript itself. Node wraps modules in a function so they have their own private scope. The only way to share in that scope is to be executed inside that function which wouldn't really work for a module (modular...) system. The only other scope is global which also isn't desirable.
The trick I used to get around it is in changing that wrapper function to have dynamic properties based on an externally defined set of module imports so that from inside the module wrapper all those parameters look like they're magically defined but aren't global.
Node's module wrapper looks like this:
Where mine simply adds more parameters and ensures they're resolved before executing the module wrapper.
I have it read a file named ".deps.json" in a given folder before loading a module.
An example one would be like this
So it will load the modules in those subfolders and then expose each one as a parameter in the wrapper, named based on the filename.
通常和干净的方法是在模块中定义一个函数,它将所需的变量作为参数:
The usual and clean way would be to define a function in your module, that takes the required variables as parameters:
您可以使用 toString() 和可怕的 eval 来更改函数作用域。
如果你的函数在 lib.js 中,如下所示:-
在 main.js 中,你可以有这样的:-
当你运行它时,ob1.foo() 行给出一个 ReferenceError,var1 未定义。这是因为 foo() 的范围来自 lib.js 而不是您的主 js 文件,并且 var1 对它不可见。 ob1.foo 是对 lib.js 作用域的函数的引用。您需要在 main.js 范围内创建新的引用。
为此,将每个函数转换为字符串并对其进行评估。这将创建一个具有相同代码但具有 main.js 范围的新函数。这是使用 setMainScope 方法的一种方法,该方法循环遍历所有函数,将其范围更改为 main.js。
现在,除了使用了
eval
之外,一切都运行良好。foo()
和bar()
的范围现在是 main.js,因此它们“看到”var1
和var2.
You can change function scope using
toString()
and the dreadedeval
.If your functions were in say lib.js as follows:-
In main.js you could have this:-
When you run it the ob1.foo() line gives a ReferenceError, var1 is not defined. This is because the scope of foo() comes from lib.js and not your main js file, and var1 is invisible to it. ob1.foo is a reference to a function with lib.js scope. You need to make a new reference with main.js scope.
To do this convert each function to string and eval it. That will create a new function with the same code but with main.js scope. Here's one way using a setMainScope method which loops through all the functions changing their scope to main.js.
Now it all works nicely except
eval
was used. The scope offoo()
andbar()
is now main.js and so they 'see'var1
andvar2
.