我有一个名为functionalUtilities的模块,它包含许多实用功能。缩写版本看起来像这样:
MYAPP.functionalUtilities = (function() {
function map(func, array) {
var len = array.length;
var result = new Array(len);
for (var i = 0; i < len; i++)
result[i] = func(array[i]);
return result;
}
return {
map:map,
};
})();
然后我有第二个包含核心代码的模块:
MYAPP.main = (function() {
//Dependencies
var f = MYAPP.functiionalUtilities;
//Do stuff using dependencies
f.map(...)
})()
每次我想使用f.map
时,都要记得输入map
,这似乎很麻烦,很烦人。当然,在依赖项中,我可以通过输入每个functionalUtilities:
var map = f.map,
forEach = f.forEach,
等
但我想知道是否有更好的方法可以做到这一点?我读过很多关于命名空间的文章都提到了别名,但是没有提出一种方法可以将对象的所有内容导入到范围中。
非常感谢您的帮助,
罗宾
[edit]为了澄清,我想在map
中使用我的功能实用程序(MYAPP.main
等),而不必每次都使用f.
这可以通过遍历MYAPP.functionalUtilities
中的每个函数并分配到MYAPP.main
中的本地范围变量来实现。但是,这需要的代码量并不能证明其好处,而且这不是一般解决方案。
答案 0 :(得分:1)
for (var i in MYAPP.functiionalUtilities) {
eval("var " + i + " = MYAPP.functiionalUtilities[i];");
}
但是我不会使用这种方法,因为你可以将带有字符串的对象属性作为这样的键:
var obj = {
"my prop": 1
};
“my prop”可能是对象属性的有效密钥,但它不是有效的标识符。因此,我建议您使用f.prop
;
var prop = f.prop
或手动定义本地变量
修改强>
正如Felix Kling在评论部分中提到的,实际上有另一种方法可以实现这一点,使用with语句,除了它已被删除之外,我并不太了解。
答案 1 :(得分:1)
这是一个迟到的答案 - 我想补充一下basilikum的答案。
with
关键字在这里很有用!with(MYAPP.functiionalUtilities) {
map(console.log, [ 'this', 'sorta', 'works', 'quite', 'nicely!' ]);
// Directly reference any properties within MYAPP.functiionalUtilities here!!
};
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with
with
关键字在某些方面适用于这种情况。当然,应该注意的是,mozilla开发人员链接不鼓励使用with
,并且在严格模式下也禁止with
。另一个问题是with
语句导致其参数成为范围链的头部,这意味着将始终首先检查with
块中所有语句的所有标识符。这可能会影响性能。
虽然函数调用无法将项添加到其父框架的范围,但是每次希望将项列表添加到命名空间时,都有一种方法可以避免输入for循环。
// First, define a multi-use function we can use each time
// This function returns a string that can be eval'd to import all properties.
var import = function(module) {
var statements = [];
for (var k in module) statements.push('var ' + i + ' = module["' + i + '"]');
return statements.join(';');
};
// Now, each time a module needs to be imported, just eval the result of import
eval(import(MYAPP.functiionalUtilities));
map(console.log, [ 'this', 'works!' ]);
这里的想法是用eval(import(MYAPP.functiionalUtilities));
替换编写for循环的需要。
像basilikum所说,这里的危险是模块属性需要是有效的标识符名称。