1

在 Node.js 中,如果我加载一个包含模块范围内代码的模块,例如:

this["foo"] = function() { console.log("foo"); }

...然后我似乎得到了一个全局可用的函数,我可以通过foo()使用该模块的任何代码来调用它。它可以看作是带有 的印刷品之一Object.getOwnPropertyNames(this)

但是,如果我将以下内容放在模块范围内:

function foo() { console.log("foo"); }

...然后它会生成一个函数,该函数可以在该模块中以类似方式调用foo(),但在其外部是不可见的(例如,不显示为带有 的项目之一Object.getOwnPropertyNames(this))。

我认为这是在浏览器中所做的运行时行为的变化。默认情况下,浏览器似乎将所有内容都放入全局范围(多年来,人们不得不通过将事物包装在匿名函数/等中来有意识地避免这种情况)

我的问题是 NodeJs 是否有一些秘密的方式来与模块之外的这些声明进行交互,在这些声明中它们被声明为BESIDES usingexports.(...) = (...) . 是否可以以某种方式枚举它们,或者如果它们没有被模块导出调用,它们是否会在声明它们时立即被垃圾收集?如果我在加载模块之前知道这样一个函数的名称......我可以告诉 Node.js 在定义它时“捕获它”吗?

我不希望有任何此类功能得到充分记录……但也许有调试器功能或其他系统调用。最好的指针之一是指向处理这种声明的 Node.js 项目中的特定代码,以查看是否存在任何漏洞。


注意:在对 V8 进行一些研究时,我发现“函数定义”没有被添加到上下文中。它被放入“执行上下文”的“激活对象”中,不能以编程方式访问。如果您想要一些“轻松阅读”,我发现:

http://coachwei.sys-con.com/node/676031/mobile

http://perfectkills.com/understanding-delete/

4

2 回答 2

2

如果你填写exports.foo = foo; 在文件的末尾,它将在节点中的其他文件中可用,假设您使用文件名执行 var myFile = require('myFile.js') 并通过 myFile.foo(); 调用该函数;您甚至可以在导出中重命名函数以供外部使用,并在使用 require 时设置您想要调用包的任何内容。

顺便说一句,您可以像在任何 JSON 对象上一样枚举这些函数(即 for k in ...)

于 2012-04-25T15:37:19.273 回答
1

如果没有像调试器这样更高级的反射工具,这在节点中是不可能的。

这样做的唯一方法是使用__parent__由于安全问题和其他原因而被删除的内容(难以优化,一开始就不是标准的)。当您运行脚本时,这些变量会在模块下关闭。如果不明确导出它们,您将无法在其他地方访问它们。

这不是错误,这是设计使然。这就是节点的工作方式。看到这个密切相关的问题

如果这种反射在没有调试器之类的工具的情况下可用,那么优化源代码将非常困难(至少 v8 的工作方式),这意味着您的问题的答案是否定的。对不起。

于 2013-04-01T10:11:47.860 回答