我不确定这是否可能,但我在这里放了一个我想要实现的示例:
(function() {
function A() {}
function B() {}
var funcs = /* how do I get both A and B programatically? */;
})();
A
和B
都不能通过在自调用函数内部访问window
和this
来访问。
我知道我可以在自调用函数中向this
添加属性A
和B
,这解决了问题,但我想知道是否有一种方法可以使用命名函数检索它们。
更新
我相信这个问题非常清楚:我想知道是否可以在不显式使用模块模式的情况下获得作用域命名函数。
最后,我希望验证我没有遗漏任何东西,也没有办法通过程序获得语法范围的命名函数。
你不能。请参见此处。
每个执行上下文都有一个与其相关联的变量对象。源文本中声明的变量和函数将作为变量对象的属性添加。
您无法访问变量对象。
如果你在php中寻找类似get_defined_vars
或python中的locals
的东西,即一个返回本地范围中定义的所有名称的函数,那么javascript中没有这样的东西,也不可能以任何方式实现它(除了将函数源代码作为字符串获取并解析它之外)。
只是为了向你展示它会变得多么丑陋:
function get_funcs(fn) {
return fn.toString().match(/functions+w+/g).map(function(x) {
return x.split(" ").pop();
});
}
(function() {
function A() { document.write('I am A<br>'); }
function B() { document.write('I am B<br>'); }
get_funcs(arguments.callee).map(function(f) {
eval(f).call();
});
})();
目前,JavaScript没有提供标准的方法来实现这一点。可以利用各种JavaScript引擎的调试功能来实现类似的效果,但我不知道如何在任何特定的引擎上做到这一点(或者他们是否允许你从"内部"完成),而且为一个引擎找到的任何解决方案都可能无法移植到任何其他引擎。
可以将这些函数收集到一个Object中,然后作为函数集合对其进行迭代。您的示例代码可能会翻译成以下内容:
var myModule = (function () {
var exports = {};
// Define your functions
function A() {};
function B() {};
// Collect the functions you want to be part of the collection
exports.A = A;
exports.B = B;
return exports;
}());
你可以更简洁地说:
var myModule = (function () {
var exports = {};
exports.A = function () {};
exports.B = function () {};
return exports;
}());
这在JavaScript世界中被称为模块模式。这个术语在更通用的计算机科学中有更广泛的含义,但在JavaScript社区中,它通常意味着实现更通用模式的特定方式(与CommonJS或AMD相反)。无论哪种方式,因为这个实现返回一个普通的Object,所以您可以像迭代其他对象一样迭代它。
您还应该调查CommonJS和AMD模块系统。如果其中任何一个都符合你想要做的事情,它们可以为你节省很多时间。