可以枚举或访问NodeJ中的模块级函数声明吗?

时间:2012-04-25 13:21:10

标签: javascript node.js module

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

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

...然后我似乎得到了一个全局可用的函数,我可以通过使用该模块从任何代码中说出foo()来调用它。它可以被视为Object.getOwnPropertyNames(this)的打印项目之一。

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

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

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

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

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

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


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

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

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

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

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

这不是一个错误,它是设计的。这就是节点的工作原理。 see this closely related question

如果没有像调试器这样的工具可以使用这种反射,那么非常很难优化源代码(至少v8的工作方式),这意味着你的问题的答案是否定的。遗憾。