【问题标题】:Possible to enumerate or access module-level function declarations in NodeJs?可以枚举或访问 NodeJs 中的模块级函数声明吗?
【发布时间】:2014-03-14 06:18:32
【问题描述】:

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

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

...然后我似乎获得了一个全局可用的函数,我只需从使用该模块的任何代码中说出foo() 即可调用该函数。可以看成是带有Object.getOwnPropertyNames(this)的印刷品之一。

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

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

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

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

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

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


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

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

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

【问题讨论】:

    标签: javascript node.js module


    【解决方案1】:

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

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

    【讨论】:

    • 啊,我应该明确表示我知道出口。我认为提到this["foo"] = function() 案例表明我知道有可能使调用模块知道声明的存在如果可以编辑模块文件。我实际上是在尝试查看是否有某种方法可以在不编辑文件的情况下挖掘文件以进行显式导出,特别是在需要者确切知道他们可能想要捕获的导出内容的情况下......
    【解决方案2】:

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

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

    这不是错误,这是设计使然。这就是节点的工作方式。 see this closely related question

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

    【讨论】:

    • 叹息。这使生活变得困难。看起来,如果您愿意妥协某些设置或参数,则可以为不需要该功能的人保留优化。哦,好吧。
    • 如果这是一个个人项目,非常欢迎您运行带有 v8 标志的 node.js,它可以让您做几乎任何事情,例如 --expose_debug_as 并破解它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多